Я создаю структуру дерева в Scala, пытаясь реализовать следующие ограничения типа:См родовыми без параметра типа в Scala
- Некорневых узлы один из трех типов - Time Node, Start Node или End узел
- корневого узел имеет только ребенок типа Time Node
- Время Nodes только дети типа Start Node
- Start Вершина только у детей типа конечного узла
- Конечных узлов могут иметь ребенок типа Start Узел или Время Узел
Это мои определения типа:
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 здесь в определении? Есть ли способ реализовать это требование, поскольку для этого потребуется гетерогенный набор для хранения ссылок на детей.
EDIT: Типы 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, который не определен.
Практически там. Теперь у меня есть метод под названием addTimeNodes(), который должен иметь возможность принимать либо RootNode, либо EndNode в качестве параметра (так как это два типа узлов, которые принимают дочерние типы типа TimeNode). Я определил черту WithTimeChildren, которая реализует классы RootNode и EndNode. Какая должна быть подпись метода addTimeNodes? addTimeNodes (node: TreeNode с WithTimeChildren) жалуется на несоответствие типов с node.ChildType, когда я пытаюсь передать TimeNode на node.addChild, что в основном связано с тем, что компилятор не знает, каким может быть ChildType в этом случае. – navjotk
@navjotk Не уверен, что вы хотите здесь точно - это addTimeNode метод на одном из типов TreeNode? Можете ли вы показать еще какой-нибудь код (или задать новый вопрос)? – Shadowlands
Обновлен вопрос. – navjotk