为什么这段代码没有打字?
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
中答案 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的标准实现中使用了类型保留形式。