如何使Scala类型推断足以发现泛型类型参数?

时间:2016-06-18 19:23:58

标签: scala type-inference type-erasure

假设我定义了一个采用隐式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无法在编译时自动推断出来?并且需要做些什么才能改进它?

1 个答案:

答案 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/20293http://scastie.org/20295的行为应该相同,所以至少有一个错误(我认为):)