scala - 如何使用 None 类型约束专门化一个特征?

标签 scala traits type-constraints

首先,如果我的问题不清楚,请让我道歉。我还没有完全掌握 Scala 的用语,所以我可能混淆了术语。不过,我认为我的例子会更清楚。

我正在尝试创建一个特征 Hierarchical它基本上描述了图中的顶点——任何可以有一个父级列表和一个子级列表的对象。

进一步来说:

  • 1) A Hierarchical可能有也可能没有 parent 。
  • 2) 如果是,则 parent 是 Hierarchical .
  • 3) A Hierarchical会有 child ,也是Hierarchical .

  • 这是我的一般特征:
    /*
      Hierarchical takes two type parameters: Parent and Child. 
      These should be Hierarchicals with parameters Parent and Child as well.
    */
    trait Hierarchical[Parent <: Hierarchical[Parent, Child],
                       Child <: Hierarchical[Parent, Child]] {
    
      // parents must be passed by constructor lest they are treated as None. 
      // (Requirement 1, 2)
      val parents: Option[List[Hierarchical[Parent, Child]]] = None
    
      // children can be added, so mutability needed (Requirement 3)
      var children: List[Hierarchical[Parent, Child]] = List()
    
      def addChild(child: Child) = children ++= List(child)
    }
    

    对此的特化是“根”顶点,其父顶点将不存在,因此根本不应指定类型——因此,它是 None .这是我尝试专注于 Hierarchical特征:
    /*
      A RootHierarchical has no parents. It does, however, have
      children whose parents are RootHierarchicals and whose children
      are Child.
      A parent can be none (Requirement 1)
    */
    trait RootHierarchical[Child <: Hierarchical[RootHierarchical, Child]]
      extends Hierarchical[None.type, Child] {
      override val parents = None
    }
    

    IntelliJ 对此很满意,但我编写的测试没有编译:
    import org.scalatest.FlatSpec
    
    class TestHierarchy extends FlatSpec {
    
      "A Hierarchical object" should "be constructable" in {
    
        /*
        Create a dummy
         */
        class DummyHierarchical(override val parents: List[DummyParentHierarchical])
          extends Hierarchical[DummyParentHierarchical, DummyHierarchical]
    
        class DummyParentHierarchical extends RootHierarchical[DummyHierarchical]
    
        val dummyParent = new DummyParentHierarchical
        val dummyChild = new DummyHierarchical(List(dummyParent))
        dummyParent.addChild(dummyChild)
    
        assert(dummyParent.parents.isEmpty)
        assert(dummyParent.children.nonEmpty)
      }
    }
    

    错误在这里:
    Error:(14, 11) type arguments [None.type,Child] do not conform to trait Hierarchical's type parameter bounds [Parent <: Hierarchical[Parent,Child],Child <: Hierarchical[Parent,Child]]
      extends Hierarchical[None.type, Child] {
    

    我的问题是:我怎样才能创建这个特化?我知道None.type不是 Hierarchical类型,但我如何专精于此?

    最佳答案

    经过一些头脑 Storm 后,我发现不需要指定父级的类型——它们可以是任意的 Hierarchical 类型,并且会有一个默认值 Nil .

    这是我的实现:

    // T is the type of children -- they should be Hierarchicals.
    trait Hierarchical[T <: Hierarchical[T]] {
      // The parents will be a list of some arbitrary Hierarchical
      val parents: List[Hierarchical[_]] = Nil
      var children: List[Hierarchical[T]] = List()
    }
    
    // Nodes that aren't root nodes will have parents specified by ctor
    class NonRootNode(override val parents: List[Hierarchical[_]]) 
      extends Hierarchical[NonRootNode] {}
    
    // Roots will have no way to update their parents.
    class Root extends Hierarchical[NonRootNode] {
      final override val parents = Nil
    }
    

    这是一个带有一些测试的小驱动程序:Ideone it

    关于scala - 如何使用 None 类型约束专门化一个特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40406241/

    相关文章:

    java - 使用scala替换字符串中的字符

    scala - 在 Spark/Scala 中保持本地、测试和生产配置属性的最佳实践

    scala - 类型参数不扩展给定类型

    c++ - 如何创建value_type类型特征?

    types - OCaml : type constraints in signatures

    swift - 无法初始化嵌套泛型

    postgresql - 使用 Anorm 执行更新返回 PSQLException : The column index is out of range: 2, 列数:1

    rust - 在继承自另一个特征的特征中指定关联类型

    scala - 为什么使用带有类型成员的特征会在子特征中给出 "error: type mismatch"?

    compiler-errors - 奇怪地重复出现的通用特征模式 : overflow evaluating the requirement