假设我定义了一个采用隐式TypeTag的函数:
def andOptionFn[A: TypeTag](g: Int => Option[A]) = {
val ttg = ScalaReflection.universe.typeTag[A]
println(ttg)
...
}
并称之为:
andOptionFn{
v =>
Some(v)
}
我希望scala类型推断能够获得正确的类型TypeTag(Option(Int)),但我得到了:
TypeTag(Option(Any)) (not even a higher kind)
为什么Scala无法在编译时自动推断出来?并且需要做些什么才能改进它?
答案 0 :(得分:1)
正确的结果是TypeTag[Int]
,Scala会打印出来:http://scastie.org/20273(将ScalaReflection
替换为scala.reflect.runtime
之后;如果ScalaReflection
是您自己的类,那就是你应该寻找问题的地方。)
编辑:http://scastie.org/20293不是一个错误,它的类型推断行为与设计完全一致。调用Seq.apply[Option[_]]
会为每个参数提供预期的Option[_]
类型。当
andOptionFn {
v =>
if (v > 1) Some(v)
else None
}
是使用此预期类型进行类型检查的,推断的R
当然是Any
。
编辑2:仔细阅读http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#local-type-inference之后,看起来似乎应该推断Int
,但我不确定。我认为Option[_]
减少到Option[Any]
(因为Option
是协变的),在这种情况下,Any
当然应该被推断。但是http://scastie.org/20293和http://scastie.org/20295的行为应该相同,所以至少有一个错误(我认为):)