The warning here is actually twofold:
1) Firstly, "a value of type () => Boolean also cannot be () => String": indeed, you are matched with () => Boolean and can never be at the same time () => String therefore chance does not make sense, and in an ideal world it should never coincide. However, erasure comes into play, as the second part hints at
2) "(but may still coincide with its erasure)": erasure here means that instances () => Boolean (aka Function0[Boolean] ) and instances () => String (aka Function0[String] ) at runtime are displayed in exactly the same way, so there is no way to distinguish between them, and when you map the template to Function0[String] , in reality the compiler can only say that it is some Function0 , but cannot know whether it is Function0[Boolean] or Function0[String] .
In anticipation of the second part of the warning, it was easy to miss here. If fl were printed Any , the first part of the warning would not apply, and you would receive a more useful message:
scala> (fl:Any) match { | case fp :Function0[Boolean] => 1 | case _ => 2 | } <console>:11: warning: non-variable type argument Boolean in type pattern () => Boolean is unchecked since it is eliminated by erasure case fp :Function0[Boolean] => 1
As for the solution, you can do little more than delegate an instance of a function. Fortunately, you do not need to write one specific shell for each possible return type. Scala provides ClassTag and TypeTag to get around erasure, and we can use it by storing it in the shell of a (common) function. However, it will be rather cumbersome to use and erroneous on the insecurity side, since you will have to match the ClassTag / TypeTag stored inside the wrapper and pass (either directly through asInstanceOf or indirectly through the same pattern match) a function with the corresponding function type .
Rรฉgis Jean-Gilles Aug 27 '15 at 10:43 on 2015-08-27 10:43
source share