How can I specialize a property with a constraint of type "No"?

First, let me apologize if my question is unclear. I haven't chosen the Scala language yet, so I'm probably combining the terms. I think my example will be clearer.

I am trying to create a feature Hierarchicalthat mainly describes the vertices in the graph — any object that can have a parent list and a list of children.

More specific:

  • 1) A Hierarchicalmay or may not have parents.

  • 2) If so, parents Hierarchical.

  • 3) A Hierarchicalwill have children, which are also Hierarchical.

Here is my common trait:

/*
  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 type parameter bounds [Parent <: Hierarchical[Parent,Child],Child <: Hierarchical[Parent,Child]]
  extends Hierarchical[None.type, Child] {

: ? , None.type Hierarchical, ?

+4
1

, - 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

+1

Source: https://habr.com/ru/post/1659748/


All Articles