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

在Scala中自键入时自动混合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

这在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
我觉得这太疯狂了。如果我们检查
条的类型
,它的
B
。如果我们翻转顺序,使得约束是
HasB和HasA
,那么
bar
就是
A

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

  • HasA与HasB
    自动生成
    {def foo:A与B}
    ,或
  • HasBoth2
    产生类型不兼容错误
  • 请解释这种不一致性,否则这是一种类型的系统错误

    更新

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

    Wrapped将满足HasBoth2的约束。

    这是预期的行为。这是scala不健全的核心问题之一

    我提供了一些解释,转载于下面的部分

    这似乎是该类型系统的一个相当基本的失败,也许是dotty动机的一部分

    抽象类型成员并不像这个词通常暗示的那样统一;它们只能被精炼。在此上下文中,这意味着创建了一个类型,该类型是B与其自身类型(即B与a)的交集。交集类型的创建假设它只能在线性化中使用最后一个“C”,因为编译将在引用检查中失败,除非最后一个“C”是任何早期“C”的细化

    这个系统以自类型分解,因为类将自己视为声明的类和声明的自类型的交集。X和Y或Y和X都可能是有效的实例化;无法先验地知道哪一个是“最后”成员C


    有关更多颜色,请参见我最后的评论。

    这里似乎只是类型与类的混淆,类型
    HasA与HasB
    只是类型约束,而
    trait hasbeath
    是试图创建类。@dmitry仍然没有解释自类型。该类型与约束性地
    null
    使用HasB强制转换为
    HasA实际上可以满足类型约束,因此它并不重要。实际上,它看起来像一个bug,或者更确切地说是一个不可预测的用例。也正如@m-z所说的,你不能用那个声明做任何事情。@dmitry那不是真的。我可以同时实现HasA和HasB。为什么你说空是唯一的情况?这里没有课程,所以绝对有可能。
    
    trait HasBoth3 extends HasA with HasB { def foo: A with B }
    type Wrapped = Wrapper[HasBoth3]