scala - Scala : Mixing traits with the “same” abstract type member

标签 scala types compiler-errors

我一直在研究Java和Scala的类型系统上的paper不够完善。为了更好地理解该问题,我一直在尝试解决一个较小的相关问题。

我有以下几种类型:

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类型不相关。因此,将它们混合可能会出现问题。

我看到可以通过提供抽象类型来创建对象/值:
object FamilyMember extends LowerBound[GrandGrandchild] with UpperBound[Parent] {
  type M = Child
}

但是我无法定义如下特征:
trait FamilyTreeConstraint extends LowerBound[GrandGrandchild] with UpperBound[Parent]

我得到:

overriding type M in trait LowerBound with bounds >: A$A131.this.GrandGrandchild; type M in trait UpperBound with bounds <: A$A131.this.Parent has incompatible type



现在,如果我没有任何具体类型,则参数化的FamilyConstraint将等效于:
trait UpperLower[T,U]{
   type M >: T <: U
}

我了解错误。因为T和U无关。

但是,上面的家庭约束类型不是抽象的,实际上具有具体的类型。即我会想到编译器最终会出现以下情况:
trait UpperLowerConcrete{
   type M >: GrandGrandchild <: Parent
}

我可以在这里将M细化为ChildGrandChild,但是它没有出现在上面,并且给出了与抽象情况相同的错误。
  • 为什么?
  • 另外,我是否认为首先应用类型细化然后再检查类型约束是正确的吗?
  • 最佳答案

    我不知道这种行为的原因,但是根据我的经验,如果更改了约束,则经常有必要在子类/特征中显式覆盖type定义。我的意思是,一旦您在M中明确指定了FamilyTreeConstraint的限制,编译器就会满足

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

    看到它online

    关于scala - Scala : Mixing traits with the “same” abstract type member,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50527797/

    相关文章:

    mysql - 哪种 MySQL 数据类型对于可扩展的应用程序来说空间效率更高?文本还是 VARCHAR?

    java - java.util.Map 键和值的运行时类型

    C# 变量和常量在溢出期间的行为不同。

    scala - 为什么我不能在 Scala 中创建 F 有界对象

    java - 如何在 Spark 中将两个 DataFrame 与组合列连接起来?

    java - 为什么用于斐波那契计算的简单 Scala tailrec 循环比 Java 循环快 3 倍?

    scala - 如何使用 maven BOM( Material list )来管理我在 SBT 中的依赖项?

    Typescript 属性类型与具有多种类型的属性相同

    c++ - g++ openCV 编译错误在线不存在

    c++ - 解决由于类之间的循环依赖而导致的构建错误