【发布时间】:2015-08-19 13:43:02
【问题描述】:
为什么不编译?
trait Lol[A, SA] {
def flatMap[B, SB](f: A => Lol[B, SB]): Lol[B, SB] = ???
}
val p1: Lol[Int, String] = ???
val p2: Lol[Double, Nothing] = ???
val p5 = p1.flatMap(_ => p2)
结果:
found : Int => Lol[Double,Nothing]
required: Int => Lol[Double,SB]
val p5 = p1.flatMap(_ => p2)
^
事情开始编译时:
-
flatMap调用的类型参数是显式的 -
SA是协变的(wtf?) -
Nothing以外的其他类型用于p2(例如Null) -
SB不会出现在flatMap的返回类型中或出现在该返回类型的协变位置(例如返回类型是Option[SB])
不过,上述解决方法对我来说是不可接受的。
【问题讨论】:
-
为什么你没有选择方差注释?通常在可能的情况下使用方差是个好主意。大部分时间使用
Nothing只有在方差下才有意义。 -
@0__
SA在给定完整的 API(此处未显示)的情况下根本无法协变。但是 - 你对Nothing是正确的 - 如果SA不是协变的,我可能可以组成我自己的特殊类型而不是使用Nothing -
尽管如此,这个错误仍然非常离奇,而且有臭虫的味道。
-
这可能是一个错误。
Nothing可能在这里由 scalac 专门处理,因为假设推理失败。如果没有人回答,我建议在issues.scala-lang.org打开一个bug
标签: scala type-inference