为什么方差注释会导致Scala无法推断出这种子类型关系?

Owe*_*wen 7 types scala covariance pattern-matching

在代码中

  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
  }
Run Code Online (Sandbox Code Playgroud)

Scala给出的错误c => c不是A => B.删除方差注释Node[+T]可以解决错误.

我很困惑,因为我相信,在存在方差注释的情况下,匹配i: I[c]应该创建规则(c => c) <:< (A => B),这就是该行编译所需的全部内容.我错过了什么?

Edm*_*984 0

免责声明:c在运行时被删除,您的匹配将无法正常工作。您正在匹配I[_]

如果您的Nodeis invariant只是 iffNode[A]的子类。这迫使Node[B]A=B

n传递到test[A, B](n: Node[A => B]) 真正 Node[A => B]

如果你推理下来,如果你匹配任何n模式,A和B必须是类型I[Something]SomethingSomething

如果 Node 是协变的,由于Function1[-A,+B]您可以调用

test[A,B](n)其中 nNode[A1 =>B1]其中A1>:AB1<:B (方程 1)

所以如果你n匹配 aI[C]就意味着A1 = C并且B1 = C

如果您替换C方程1,您将得到C >: AC<:B (方程 2)

因此以下分配不再有效

f: A => B = C => C 
Run Code Online (Sandbox Code Playgroud)

为了可以从右侧分配左侧,我们C => C需要Function1[-A,+B]

这意味着A >: CB <: C但从等式 2 我们知道这不成立(除了 C = A 和 C = B 的情况,并且没有证据表明这种情况,除非你的 Node 是不变的