In Scala, how to circumvent 'inferred type arguments do not conform' error?

时间:2016-06-18 19:57:32

标签: scala type-erasure scala-compiler

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.

1 个答案:

答案 0 :(得分:1)

这不是改进,恰恰相反,Scala类型推断根本不支持首先推断Opt并从那里获取R:而是推断Nothing因为{ {1}}不是任何参数类型的一部分(返回类型未知)。

您可以通过在每次调用中明确指定类型参数来绕过它:R。我认为,给出预期类型也应该适用于这种特定情况:fromOptionFn2[String, Option[String]](...)。但是,更好的想法是不要首先使用类型参数签名,如fromOptionFn2(...): Wrapper[String]