为什么不编译?
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]
)然而,上述解决方法对我来说是不可接受的。
答案 0 :(得分:2)
为了更好地理解您的问题,可将其简化为:
class Lol[A]
def foo[B](f: Lol[B]) = f
foo(new Lol[Nothing])
,它会给你以下编译错误:
error: type mismatch;
found : Lol[Nothing]
required: Lol[B]
Note: Nothing <: B, but class Lol is invariant in type A.
You may wish to define A as +A instead. (SLS 4.5)
一种可能的解决方案是更新代码片段:
def foo[B <: Lol[_]](f: B) = f
返回原始代码:
trait Lol[A, SA] {
def flatMap[B <: Lol[_,_]](f: A => B): B = ???
}
答案 1 :(得分:2)
@ retronym对SI-9453的评论解释了你所看到的行为。这是一种解决方法......
我们可以合成一个等同于Nothing
的类型,它不会导致typer收回推理解决方案,
type ReallyNothing = Nothing { type T = Unit }
即。 Nothing
带有虚拟细化。现在以问题为例,
scala> :paste
// Entering paste mode (ctrl-D to finish)
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, ReallyNothing] = ???
val p5 = p1.flatMap(_ => p2)
// Exiting paste mode, now interpreting.
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
... 37 elided