在Scala中,是否缺少协方差的传递规则



例如

trait AA[+X[n], +Y] {
def x: X[Y] // [Error]: covariant type Y occurs in invariant position in type => X[Y] of method x
}

这似乎是错误的消息,因为X[Y]可以很容易地被证明是协变的:

如果Y1>:>Y2、+X1[n]>:>X2[n]对于所有n,则:

Y1>:>Y2

(X2的协方差)=>X2[Y1]>:>X2[Y2]

(X1[Y1]>:>X2[Y1])=>X1[Y1]>:>X2[Y2]

是什么原因导致了此错误消息?

您又缺少一个+。正确的是

trait AA[+X[+n], +Y] {
def x: X[Y]
}

则类型X将是协变的(相对于其类型参数n)并且位置

def x: X[...]
//         ^^^  <- this position

将是协变的,并且您将能够在该位置使用协变类型参数Y

相反,您声明了不变类型X(w.r.t.n),并试图在不变位置使用协变类型参数Y

有不同的概念:

  • 协变/反变/不变类型参数(+T-TT)

  • 协变/反变/不变类型,即类型构造函数,相对于其类型参数(T1 <: T2 => A[T1] <: A[T2]T1 <: T2 => A[T1] >: A[T2]或它们中的任何一个)

  • 根据规则的协变/逆变/不变位置https://scala-lang.org/files/archive/spec/2.13/04-basic-declarations-and-definitions.html#variance-注释

+X[n]AA的协变型参数,但相对于其类型参数n是不变型。

以下结论不正确:

(X2的协方差)=>X2[Y1]>:>X2[Y2]

同样正确的做法是使Y不变

trait AA[+X[n], Y] {
def x: X[Y]
}

顺便说一句,昨天Oleg Nizhnikov(@odomontois)进行了方差训练(以及其他主题)https://youtu.be/l08tK1x89ho?t=7494(从2:04:54开始)。

相关内容

  • 没有找到相关文章

最新更新