Scala Self Type и this.type в выпуске коллекций

Я пытаюсь обернуть голову вокруг абстрактных и явных типов себя в scala. Давайте рассмотрим этот пример: я хочу создать базу для расширяемого дерева так просто:

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

Тем не менее, я хочу иметь возможность расширять узлы дерева с помощью некоторых методов и использовать эти методы, такие как:tree.children foreach { _.newMethod() }

Для этого я попробовал:

A. 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 })
    }
}

Рабочий вариант довольно неуклюжий.

B. Абстрактные типы: 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 })
    }
}

Как я понял, не работает вообще из-за несоответствия типа конкретного пути.

C. Тип params (дженерики): ОК

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

    def children: Iterable[Node]

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

Работает нормально, но не очень хорошо для поддержки в производных классах.

Есть идеи, как сделать первые два варианта работающими без тонны кода?

Кроме того, с this.type у меня возникли проблемы с реализацией.

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 {
  // ...
}

Спасибо!

Ответы на вопрос(2)

Ваш ответ на вопрос