我正在 Scala 中创建一个树结构,试图实现以下类型限制:
- 非根节点是三种类型之一 - 时间节点、开始节点或结束节点
- 根节点只有时间节点类型的子节点
- 时间节点只有开始节点类型的子节点
- 开始节点只有结束节点类型的子节点
- 结束节点可能有类型为开始节点或时间节点的子节点
这些是我的类型定义:
trait TreeNode[U] {
val children:HashSet[NonRootNode[U]]
def addChild(c:NonRootNode[U])
}
class NonRootNode[T <: TreeNode[T]] extends TreeNode[T] {
var passengers:Set[Passenger] = Set()
val children:HashSet[T] = new HashSet[T]
def addChild(c:T) = {
children.add(c)
}
}
case class RootNode extends TreeNode[TimeNode] {
val children:HashSet[TimeNode] = new HashSet[TimeNode]
def addChild(c:TimeNode) = {
children.add(c)
}
}
case class TimeNode(time:Int) extends NonRootNode[StartNode] {
}
case class StartNode(l:Option[String]) extends NonRootNode[EndNode] {
}
case class EndNode(l:Option[String]) extends NonRootNode {
}
首先,这是否正确实现了要求 1-4?其次,有没有办法在定义中实现要求 5?有没有办法实现这个要求,因为这需要一个异构集来存储子引用。
编辑: RootNode 和 EndNode 类型需要如下方法:
trait ParentOfTimeNode extends TreeNode{
//type ChildType = TimeNode
def addTimeNodes(startTime:Int, maxTime:Int) = {
for(i <- startTime to maxTime) {
this.addChild(new TimeNode(i))
}
}
}
如果没有注释该行,则尖叫的行是:
case class EndNode(l:Option[String]) extends NonRootNode with ParentOfTimeNode{ type ChildType = NonRootNode with IntervalMarker }
因为明显的类型匹配。注释了该行后, this.addChild 尖叫,因为它被未定义的 ChildType 绑定。