Scala self type y this.type en el número de colecciones

Estoy tratando de entender mis propios tipos abstractos y explícitos en scala. Consideremos este ejemplo: quiero crear una base para un árbol extensible tan simple como esto:

trait Tree {
  def children: Iterable[Tree]
  def descendants: Iterable[Tree] = { val dv = children.view; dv ++ (dv.flatMap { _.children }) }
}

Sin embargo, quiero poder extender nodos de árbol con algunos métodos y usar estos métodos como:tree.children foreach { _.newMethod() }

Para esto he intentado:

UN. this.type: FAIL

trait Tree {
    def children: Iterable[this.type] 
    def descendants: Iterable[this.type] = {
      val dv = children.view
      // FAIL: type mismatch;  found   :  scala.collection.IterableView[com.abovobo.data.Tree,Iterable[_]]  required: Iterable[Tree.this.type] 
      // dv ++ (dv.flatMap { _.children })
      // OK: 
      dv.++[this.type, Iterable[this.type]](dv.flatMap[this.type, Iterable[this.type]]{ _.children })
    }
}

as variantes de trabajo son bastante torpe

SI. Tipos de resumen: FAIL

trait Tree {
    type Node <: Tree

    def children: Iterable[Node]  
    def descendants: Iterable[Node] = {
        val dv = children.view
        // FAIL: type mismatch;  found   : scala.collection.IterableView[com.abovobo.data.Tree#Node,Iterable[_]]  required: Iterable[Tree.this.Node] 
        dv ++ (dv.flatMap { _.children })
    }
}

No funciona en absoluto debido a la falta de coincidencia del tipo específico de ruta como lo entendí.

C. Parámetros de tipo (genéricos): OK

trait Tree[+Node <: Tree[Node]] {

    def children: Iterable[Node]

    def descendants: Iterable[Node] = {
       val dv = children.view
       dv ++ (dv.flatMap { _.children })
    }
}

Funciona bien, pero no es tan bueno para mantener en clases derivadas.

Alguna idea de cómo hacer que las dos primeras variantes funcionen sin toneladas de código?

Además, con this.type me he encontrado con problemas con la implementación.

trait BiDTree extends Tree {
    def parent: Option[this.type]
}

// how to accept this param? Option[TreeImpl] doesn't work. 
class TreeImpl(val parent: Option[???]) extends BiDTree {
  // ...
}

¡Gracias

Respuestas a la pregunta(4)

Su respuesta a la pregunta