Circular type parameters definition in scala

generics, scala, type-parameter

Solution

The other solutions already given fail to enforce that the types match: that is, given a type `ContainerImpl extends Container`, you should be sure that `ContainerImpl.E.C` should be `ContainerImpl` and not some other container. Here is one which does enforce this (adapted from http://programming-scala.labs.oreilly.com/ch13.html):

abstract class ContainerWithElement {
  type C <: Container
  type E <: Element

  trait Container {
    self: C =>
    def contains( e: E ): Boolean
    def addNewElement(): Unit
  }

  trait Element {
    self: E =>
    def enclosingContainer(): C
  }
}

Problem

I am trying to define a generic container whose elements can return the enclosing container. Something like: ``` abstract class Container[E <: Element] { // compile error def contains( e: E ): Boolean def addNewElement(): Unit } abstract class Element[C <: Container] { // compile error def enclosingContainer(): C } class MyContainer extends Container[MyElement] { private var elements = List[MyElement]() override def contains( elem: MyElement ) = elements.contains( elem ) override def addNewElement() { elements ::= new MyElement(this) } } class MyElement( container: MyContainer ) extends Element[MyContainer] { override val enclosingContainer = container } ``` However that snippet does not compile because I should give a type parameter to `Element` in the `abstract class Container[E <: Element]` definition and a type to `Container` in the `abstract class Element[C <: Container]` definition. I there a way to achieve the behavior I am looking for ? Is there an appropriate declaration for `Container` and `Element`? Should I define a third-party object ?

Original source