Scala:将特征与“相同”抽象类型成员混合

时间:2018-05-25 11:06:59

标签: scala types compiler-errors

我一直在关注Java类型系统上的paper和Scala是不健全的。为了更好地理解这个问题,我一直试图解决一个较小的相关问题。

我有以下类型:

class Parent
class Child extends Parent
class Grandchild extends Child
class GrandGrandchild extends Grandchild

以下是一些约束抽象类型的特征:

trait LowerBound[T] extends{
  type M >: T
}

trait UpperBound[U] extends{
  type M <: U
}

我理解这里出现的问题是TU中的UpperBoundLowerBound类型无关。因此混合它们可能会有问题。

我可以看到我可以通过提供抽象类型来创建一个对象/ val:

object FamilyMember extends LowerBound[GrandGrandchild] with UpperBound[Parent] {
  type M = Child
}

但我未能定义如下特征:

trait FamilyTreeConstraint extends LowerBound[GrandGrandchild] with UpperBound[Parent]

我明白了:

  

在特征LowerBound中覆盖类型M,边界大于&gt;:A $ A131.this.GrandGrandchild;    在特征UpperBound中键入M,边界&lt ;: A $ A131.this.Parent具有不兼容的类型

现在,如果我没有任何具体类型,参数化FamilyConstraint将等同于:

trait UpperLower[T,U]{
   type M >: T <: U
}

我理解错误。因为T和U是无关的。

但上面的Family Constraint类型不是抽象的,实际上有具体的类型。即我想象编译器最终得到这个:

trait UpperLowerConcrete{
   type M >: GrandGrandchild <: Parent
}

我将被允许将M精简为ChildGrandChild。但是,它不会变成上面的并且给出与抽象情况相同的错误。

  • 为什么呢?

  • 另外,我是否认为先应用类型优化然后检查类型约束?

1 个答案:

答案 0 :(得分:1)

我不知道这种行为的原因,但根据我的经验,如果其约束条件发生变化,通常需要在子类/特征中显式覆盖type定义。我的意思是,一旦在M中明确指定FamilyTreeConstraint的限制,编译器就会满意

trait FamilyTreeConstraint extends LowerBound[GrandGrandchild] with UpperBound[Parent] {
  override type M >: Grandchild <: Parent
}

online