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

时间:2014-05-04 17:40:20

标签: scala types pattern-matching covariance

在代码中

  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),这就是该行编译所需的全部内容。我错过了什么?

1 个答案:

答案 0 :(得分:0)

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

上进行了匹配

如果您的Node不变Node[A],则只有if Node[B]才是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)其中nNode[A1 =>B1]其中A1>:AB1<:B (等式1)

因此,如果您的nI[C]匹配,则表示A1 = CB1 = C

如果您替换等式1 中的C,您将获得C >: AC<:B (等式2)

因此,以下作业不再有效

f: A => B = C => C 

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

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