Scala 中的协方差
Covariance in Scala
我正在学习 Functional Programming Principles in Scala, as I went through the lecture Subtyping and Generics,我对协方差感到困惑:
给定:NonEmpty <: IntSet
或 NonEmpty
是 IntSet
的子类型
是List[NonEmpty] <: List[IntSet]
或List[NonEmpty]
是
List[IntSet]
?
答案是有道理的,因为非空集列表是任意集列表的特例。
这个答案是否暗示 List[NonEmpty]
是 List[IntSet]
的子类型?
所以我尝试了这个:
val nonEmpty: List[NonEmpty] = null
val intSet: List[IntSet] = nonEmpty
然后我得到一个编译错误:
Expression of type List[NonEmpty] doesn't conform to expected type
List[IntSet]
据我所知,泛型在 Java 中是不变的,泛型在 Scala 中是协变的吗
或者我对协方差有错误的理解?
编辑:
这里是IntSet, NonEmpty, List
的定义:
abstract class IntSet {
def contains(x: Int): Boolean
def incl(x: Int): IntSet
def union(other: IntSet): IntSet
}
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {...}
trait List[T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
}
首先,你应该知道的是
In Scala, however, generic types have by default nonvariant
(or, "rigid") subtyping
covariance
表示
if S is a subtype of type T, then should List[S] be considered a subtype of List[T]
nonvariant
还有一个意思就是
if S is a subtype of type T, then should List[S] not be considered a subtype of List[T]
document 会帮助你。只需搜索 covariance
这个词,您就会找到问题的答案。
祝你好运
问题出在你对List
的定义上;它的类型参数没有前缀 +
来表示类型参数是协变的。改成这样:
trait List[+T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
}
我正在学习 Functional Programming Principles in Scala, as I went through the lecture Subtyping and Generics,我对协方差感到困惑:
给定:NonEmpty <: IntSet
或 NonEmpty
是 IntSet
是List[NonEmpty] <: List[IntSet]
或List[NonEmpty]
是
List[IntSet]
?
答案是有道理的,因为非空集列表是任意集列表的特例。
这个答案是否暗示 List[NonEmpty]
是 List[IntSet]
的子类型?
所以我尝试了这个:
val nonEmpty: List[NonEmpty] = null
val intSet: List[IntSet] = nonEmpty
然后我得到一个编译错误:
Expression of type List[NonEmpty] doesn't conform to expected type List[IntSet]
据我所知,泛型在 Java 中是不变的,泛型在 Scala 中是协变的吗 或者我对协方差有错误的理解?
编辑:
这里是IntSet, NonEmpty, List
的定义:
abstract class IntSet {
def contains(x: Int): Boolean
def incl(x: Int): IntSet
def union(other: IntSet): IntSet
}
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {...}
trait List[T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
}
首先,你应该知道的是
In Scala, however, generic types have by default
nonvariant
(or, "rigid") subtyping
covariance
表示
if S is a subtype of type T, then should List[S] be considered a subtype of List[T]
nonvariant
还有一个意思就是
if S is a subtype of type T, then should List[S] not be considered a subtype of List[T]
document 会帮助你。只需搜索 covariance
这个词,您就会找到问题的答案。
祝你好运
问题出在你对List
的定义上;它的类型参数没有前缀 +
来表示类型参数是协变的。改成这样:
trait List[+T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
}