Аналогично взаимно-рекурсивным типам в scala я пытаюсь создать взаимно-рекурсивный тип в Scala .
Я пытаюсь создать график, определенный с помощью этого типа (который компилируется):
case class Node(val id : Int, val edges : Set[Node])
Но я не понимаю, как я вообще могу создать что-то с этим типом, потому что для того, чтобы инициализировать Node A с ребрами B и C, мне нужно как минимум иметь ленивую ссылку на B и C, но я не могу одновременно создать их наборы ребер.
Можно ли реализовать этот рекурсивный тип?
РЕДАКТИРОВАТЬ:
Вот решение, которое я сейчас использую для преобразования явного списка смежности в самореферентный.
def mapToGraph(edgeMap : Map[Int, mutable.Set[Int]]) : List[Node] = {
lazy val nodeMap = edgeMap map (kv => (kv._1, new Node(kv._1, futures.get(kv._1).get)))
lazy val futures : Map[Int, Set[Node]] = edgeMap map (kv => {
val edges = (kv._2 map (e => nodeMap.get(e).get)).toSet
(kv._1, edges)
})
val eval = nodeMap.values.toList
eval //to force from lazy to real - don't really like doing this
}
или, альтернативно, из списка краев
//reads an edgeList into a graph
def readEdgelist(filename : String) : List[Node] = {
lazy val nodes = new mutable.HashMap[Int, Node]()
lazy val edges = new mutable.HashMap[Int, mutable.Buffer[Node]]()
Source.fromFile(filename).getLines() filter (x => x != None) foreach {edgeStr =>
val edge = edgeStr.split('\t')
if (edge.size != 2) goodbye("Not a well-formed edge : " + edgeStr + " size: " + edge.size.toString)
val src = edge(0).toInt
val des = edge(1).toInt
if (!(nodes.contains(src))) nodes.put(src, new Node(src, futures.get(src).get))
if (!(nodes.contains(des))) nodes.put(des, new Node(des, futures.get(des).get))
edges.put(src, edges.getOrElse(src, mutable.Buffer[Node]()) += nodes.get(des).get)
}
lazy val futures : Map[Int, Set[Node]] = nodes map {node => (node._1, edges.getOrElse(node._1, mutable.Buffer[Node]()).toSet)} toMap
val eval = nodes.values.toList
eval
}
Спасибо всем за советы!
val
объявления в случае, если классы избыточны - person Nikita Volkov   schedule 13.10.2012