Reputation: 3858
I have a reflective function with implicit TypeTag parameter:
def fromOptionFn[R: TypeTag](self: Int => Option[R]): Wrapper[R] = {
println(TypeTag[R])
...
}
Which for unknown reason doesn't work (see How to make Scala type inference powerful enough to discover generic type parameter?):
> fromOptionFn2(v => Some(" + _))
> typeTag(Any)
I speculate that its caused by inferring R from Option[R], so I improve it a bit:
def fromOptionFn[R, Opt <: Option[R]: TypeTag](self: Int => Opt): Wrapper[R] = {
println(typeTag[Opt])
...
}
This time its worse, doesn't even compile, the error clearly inferred that scala is not smart enough to analyse the type:
> fromOptionFn2(v => Some(" + _))
Error: inferred type arguments [Nothing,Option[String]] do not conform to method fromOptionFn's type parameter bounds [R,Opt <: Option[R]]
So how do I temporarily circumvent this compilation problem? (Of course I can report it on Lightbend issue tracker but its too slow)
ADDENDUM: This problem itself is an attempted circumvention for How to make Scala type inference powerful enough to discover generic type parameter?, which might won't be fixed. In my case I don't mind getting the TypeTag of type R or Option[R], whatever works works.
Upvotes: 2
Views: 986
Reputation: 170839
This isn't an improvement, just the opposite, and Scala type inference simply doesn't support inferring Opt
first and getting R
from there: instead it infers Nothing
because R
isn't a part of any parameter types (and return type is unknown).
You could circumvent it by specifying the type parameters explicitly on every call: fromOptionFn2[String, Option[String]](...)
. Giving the expected type should also work in this specific case, I think: fromOptionFn2(...): Wrapper[String]
. However, a better idea would be not to use type parameter signatures like [R, Opt <: Option[R]]
in the first place.
Upvotes: 1