Bizzare类型推理限制 - 多种类型的参数

ghi*_*hik 8 scala type-inference

为什么这不编译?

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)
Run Code Online (Sandbox Code Playgroud)

结果:

found   : Int => Lol[Double,Nothing]
required: Int => Lol[Double,SB]
   val p5 = p1.flatMap(_ => p2)
                         ^    
Run Code Online (Sandbox Code Playgroud)

事情开始编译时:

  • 类型的flatMap调用参数是显式的
  • SA 是协变的(wtf?)
  • 除了(例如)Nothing使用的其他类型p2Null
  • SB在返回类型中不会发生flatMap或在该返回类型的协变位置发生(例如返回类型Option[SB])

但是,上述解决方法对我来说是不可接受的.

Mil*_*bin 2

@retronym 对SI-9453 的评论解释了您所看到的行为。这是一种解决方法......

我们可以合成一个等价的类型Nothing,不会导致打字员撤回推理解决方案,

type ReallyNothing = Nothing { type T = Unit }
Run Code Online (Sandbox Code Playgroud)

IE。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
Run Code Online (Sandbox Code Playgroud)