在Scala中自键入时自动混合api

  • 本文关键字:混合 api Scala scala
  • 更新时间 :
  • 英文 :


这在scala中是出乎意料的(或者我的预期是错误的)。下面是一些示例代码:

trait A
trait B
trait HasA { def foo: A }
trait HasB { def foo: B }

到目前为止还不错,然后我做

scala> trait HasBoth extends HasA with HasB
<console>:11: error: overriding method foo in trait HasA of type => A;
 method foo in trait HasB of type => B has incompatible type
       trait HasBoth extends HasA with HasB

好吧,我看到错误了。这是有道理的。

但混乱随之而来:

trait Wrapper[T] { def get: T }
trait HasBoth2 { self: Wrapper[HasA with HasB] => def bar = get.foo }

我发现这太疯狂了。如果我们检查bar的类型,它的B。如果我们翻转顺序,使得约束是HasB with HasA,那么bar就是A

所以我们有一些不一致的地方。我希望:

  1. HasA with HasB自动生成{ def foo: A with B },或
  2. HasBoth2产生类型不兼容错误

请解释这种不一致性,或者这是一个类型系统错误。

更新

trait HasBoth3 extends HasA with HasB { def foo: A with B }
type Wrapped = Wrapper[HasBoth3]

Wrapped将满足HasBoth2的约束。

这是预期的行为。它是scala不稳定的核心点之一。

SI-7278:

我在SI-7255中提供了一些解释,转载于下文部分。

这似乎是类型系统的一个相当根本的失败,可能也是多蒂的部分动机

抽象类型的成员并不像这个词通常暗示的那样统一;它们只能被提炼。在这种情况下,这意味着创建了一个类型,它是B与其自身类型的交集,也就是说,B与a的交集。创建交集类型时假设它只能在线性化中使用最后一个"C",因为除非最后的"C"是任何早期"C"的精化,否则编译将在refcheck中失败

这个系统因self-type而崩溃,因为类将自己视为具有声明类和声明self-type的交集。X与Y或Y与X可能是有效的实例化;没有办法先验地知道哪一个是"最后一个"成员C。

有关更多颜色,请参阅我对SI-7472的最后一条评论。

最新更新