如何在非同质,不可变树中正确建模节点?

时间:2012-01-23 05:28:48

标签: scala

我需要在树中建模节点。当然,节点有子节点,并且存在节点的继承层次结构:

trait Node extends Seq[Node] { 
  val children:List[Node] = List()
  def apply(n:Int) = children(n)
  def iterator = children.iterator
  def length = children.length
  def add(n:Node):Node = { ??? }
}
case class NodeA(n:Int) extends Node
case class NodeB(n:String) extends Node
case class NodeC(c:String) extends NodeB(c)

val na:NodeA = new NodeA(1)
val na1:NodeA = na.add(new NodeB("a"))
na1.children == List(NodeB("a"))
val na2:NodeA = na1.add(new NodeC("b"))
na2.children == List(NodeB("a"), NodeC("b"))

这里的问题是我想保持Node及其子类不可变。

那时我才开始遇到问题。如何在Node上正确编写方法.add?因为显然调用NodeA.add应该返回NodeA,而不是Node 即使我将所有特定于节点的方法实现(childrenaddremove)放入每个子类(或配对对象,构建器,CanBuildFrom等),附带损害也是如此。 ,然后我需要将children定义为构造函数参数。哪个会破坏Node子类的定义和用法 - 如果可能的话我应该避免使用它。

这可能吗?或者我做错了什么,还有另一种方法吗?

1 个答案:

答案 0 :(得分:3)

您是否在询问如何抽象add的返回类型?如果是这样,您可能需要查看functional dependencies。另请参阅Scala集合中的CanBuildFrom,如herehere所述。