【问题标题】:Scala 2.11 Type Variance ChangesScala 2.11 类型差异更改
【发布时间】:2014-06-16 13:51:24
【问题描述】:

在 Scala 2.10.4 中编译:

trait Foo[-U,T]{
  type Contra = U
}

但在 2.11.0 中同样失败:

逆变类型U出现在类型U的不变位置 Contra trait Foo[-U,T] {type Contra = U}

是否有可用的解决方法?尝试将 Scala 库移植到 2.11 并且需要逆变类型才能让编译器获取大量隐式 def(即,使 U 保持不变似乎不是一种选择)。

谢谢

【问题讨论】:

  • 您能详细解释一下如何使用类型成员和逆变来控制隐式解析吗?我有兴趣了解更多有关此问题的信息,也许在问题更深的地方有解决方法。
  • 你能用type Contra >: U吗?
  • @n.m.我不能使用 Contra >: U 作为依赖于 U 的实例,期望 U 而不是 U 的超类型(即,当尝试这种方法时,编译器会说方法 X 不是 Contra 的成员)
  • @wingedsubmariner U 必须是 Foo 的逆变类型参数,但 U 是整个库中使用的隐式证据中的协变类型。基本上,在 Foo 中,Contra 必须完全等于 U,但在其他任何地方都被视为 contra/covariant。 2.11 的快速和肮脏是@uncheckedVariance
  • 但是您可以将 U 的某些超类型传递给扩展 Foo 的类,情况完全相同。

标签: scala variance implicits


【解决方案1】:

我无法想象有可用的解决方法。我说这一切的原因都是为了支持依赖路径的类型:

 def foo[T <: Foo[A,B]](that: T): that.Contra

这会将Contra 类型放在错误的位置。您不能作为操作的结果返回逆变类型。也许这些的搜索和验证需要大量工作,以至于编译器作者认为这个小角落案例造成了太大的负担或者这是您发现的编译器错误。

顺便说一句,这只是我的疯狂猜测。我必须阅读编译器代码才能确定哪种方式是哪种方式。

【讨论】:

  • +1 为例,确认 2.11 中的更改。有关详细信息,请参阅我的答案中的链接错误线程。
【解决方案2】:

在类型检查器中显然是 2.7 和 2.11 之前的 this was a bug。现在OP中的预防方法是一个特性,这是一件好事,有点o_O

解决方法是像 2.11 之前的那样做,不同之处在于现在您知道您是靠自己的,而不是之前您认为编译器支持你。

无知是福,对吧?

解决方法:

import annotation.unchecked._
trait Foo[-U,T]{
  type Contra = (U @uncheckedVariance)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    相关资源
    最近更新 更多