简体   繁体   中英

Scala mixin Node trait

I am trying to make a trait which I can mixing to an class to define it as a tree node. Finding an elegant way of doing this is turning out to be problematic.

The following just doesn't work, as this.type causes a type mismatch when you assign a parent

trait Node {
  def parent:Option[this.type]
  def root:this.type =
    parent.fold(this)(_.root)
}

This kind of works but the T value could get miss-assigned, and the casting is pretty ugly.

trait Node[T <: Node[T]] {
  def parent:Option[T]
  def root:T =
    parent.fold(this)(_.root).asInstanceOf[T]
}

Any ideas of a stricter approach?

trait Node[+T] {
  def parent: Option[Node[T]]
  def root: Node[T] = parent.fold(this)(_.root) // root is node as well, isn't it?
}

class Foo extends Node[Foo] { def parent = None }

You can add a self-type to avoid the cast:

trait Node[T <: Node[T]] { self: T =>
  def parent: Option[T]
  def root: T = parent.fold(this)(_.root)
}

You can additionally return T with Node[T] instead of plain T , but I'm not sure if that gives real benefits beyond what the self-type gives you:

trait Node[T <: Node[T]] { self: T =>
  def parent: Option[T with Node[T]]
  def root: T with Node[T] = parent.fold(this)(_.root)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM