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

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

最佳答案

免责声明: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)哪里nNode[A1 =>B1]哪里A1>:AB1<:B (等式 1)

所以如果您的 n匹配 I[C]这意味着 A1 = CB1 = C
如果更换 C方程 1 , 你会得到 C >: AC<:B (方程 2)

因此以下分配不再有效

f: A => B = C => C 

为了让左侧可以从右侧分配,我们需要 C => C成为 Function1[-A,+B]
这意味着 A >: CB <: C但是从等式 2 我们知道这不成立(除了 C = A 和 C = B 的情况,并且没有证据表明这种情况,除非您的 Node 是 不变 )

关于scala - 为什么方差注释会导致 Scala 无法推断出这种子类型关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23459423/

相关文章:

scala - 在 sbt 11.2 中更改 war 文件名

F# 对具有可选字段的记录进行模式匹配

Javascript:使用正则表达式检查一个字符串是否仅包含另一个字符串的值?

scala - 如何系统地避免 Scala 中的不安全模式匹配?

scala - 将第一个列表的元素分发到另一个列表/数组

scala - 函数等于 Scala 中函数的默认值

c - Haskell 到 C - 自定义数据类型

python - TypeError : tuple indices must be integers, 不是元组

scala - 如何避免由于 akka actor 中的锁定超时而丢失消息?

types - OCaml 的 "ground coercion"是什么?