为什么scala不能推断Left [X,A]是[X,B]的合理子类型?

时间:2012-08-07 14:52:01

标签: scala type-systems

为什么这段代码没有打字?

def foo: Either[String, List[Int]] = {  
  val x = null: Either[String, String]

  x match {
    case l @ Left(_) => l
    case Right(_) => Right(List(3))
  }
}

具体来说,为什么编译器不能/不能将左[A,X]和[A,B]的类型重新设定?

这发生在scala 2.8.2和scala 2.9.2

1 个答案:

答案 0 :(得分:9)

这里存在真正的冲突:

Left[String, String] <: Either[String, List[Int]]

不是真的。在{em>左右参数上输入Left,即使两者之间没有实际差异(因此铸造是安全的),这是< em>不是你告诉编译器的。所以,当然,它会抱怨。

模式匹配中的类型推断存在其他缺点,但这不是其中之一。


编辑:可以想象Left的替代单参数化实现

Left[String] <: Either[String, Nothing] <: Either[String, List[Int]]

会抛弃类型信息。像swap这样的方法可以使用,但它会允许OP给出的模式。但是,在Scala的标准实现中使用了类型保留形式。