在代码中
sealed trait Node[+T]
case class I[C]() extends Node[C => C]
def test[A, B](n: Node[A => B]) = n match {
case i: I[c] =>
val cId: c => c = identity _
val ab: A => B = cId
}
Scala 给出的错误是
c => c
不是 A => B
.删除 Node[+T]
中的方差注释解决了错误。我很困惑,因为我相信,在存在方差注释的情况下,匹配
i: I[c]
应该创建规则 (c => c) <:< (A => B)
,这是该行编译所需的全部内容。我错过了什么?
最佳答案
免责声明:c
在运行时被删除,您的匹配将无法正常工作。您正在匹配 I[_]
万一您的 Node
是不变的 Node[A]
是 Node[B]
的子类只有 iff A=B
.这迫使n
传递给 test[A, B](n: Node[A => B])
成为真正的Node[A => B]
如果你推理下来,如果你的n
匹配模式 I[Something]
随便 Something
, A 和 B 的类型必须是 Something
如果 Node 是协变的,因为 Function1[-A,+B]
的定义你可以调用test[A,B](n)
哪里n
是 Node[A1 =>B1]
哪里A1>:A
和 B1<:B
(等式 1)
所以如果您的 n
匹配 I[C]
这意味着 A1 = C
和 B1 = C
如果更换 C
在 方程 1 , 你会得到 C >: A
和 C<:B
(方程 2)
因此以下分配不再有效
f: A => B = C => C
为了让左侧可以从右侧分配,我们需要
C => C
成为 Function1[-A,+B]
这意味着
A >: C
和 B <: C
但是从等式 2 我们知道这不成立(除了 C = A 和 C = B 的情况,并且没有证据表明这种情况,除非您的 Node 是 不变 )
关于scala - 为什么方差注释会导致 Scala 无法推断出这种子类型关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23459423/