Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala DAG更新多个父级_Scala_Data Structures_Immutability - Fatal编程技术网

Scala DAG更新多个父级

Scala DAG更新多个父级,scala,data-structures,immutability,Scala,Data Structures,Immutability,我已经知道不可变的数据结构在Scala中不能有循环 但是,如何处理多个家长的子更新 val child = Child("Tom") val mother = Parent("Susi", child) val father = Parent("Chuck", child) val renamedChild = child.copy(name = "Tommy") // how to update both references? 我对Zipper没有太多了解,但我认为它们只适用于简单的树,而

我已经知道不可变的数据结构在Scala中不能有循环

但是,如何处理多个家长的子更新

val child = Child("Tom")
val mother = Parent("Susi", child)
val father = Parent("Chuck", child)
val renamedChild = child.copy(name = "Tommy")
// how to update both references?

我对Zipper没有太多了解,但我认为它们只适用于简单的树,而不是DAG,对吗?

在不可变/持久数据结构中,您有结构共享,因此在执行更新时,必须更新整个结构的一部分。对于树这样的层次结构(如您的示例所示),这意味着您必须从上到下更新从根到子的路径。这反过来又要求你了解你的父母

如果
母亲
父亲
在没有根的情况下“自由浮动”,您也必须更新它们:

val mother1 = mother.copy(child = renamedChild)
val father1 = father.copy(child = renamedChild)
如果您有嵌套的数据结构,并且希望避免手动记账(这很容易导致错误),则可以使用以下方法:

如果您的结构是一个有向无环图,那么找到一个不可变的实现可能是一个挑战(我不知道有一个持久的DAG结构,它可能是可行的,将DAG分解为一组树,但我没有遇到任何这样的实现)


当然,你总是可以有一个幼稚的(表现不好的)版本

// set of vertices and map that points from children to parents!
type Graph[A] = (Set[A], Map[A, Set[A]])

def update[A](graph: Graph[A], before: A, now: A): Graph[A] = {
  val (vertices, edges) = graph
  val newV    = vertices - before + now
  val parents = edges.getOrElse(before, Set.empty)
  val newE    = if (parents.isEmpty) edges else edges - before + (now -> parents)
  (newV, newE)
}

val g1 = Set("Tom", "Susi", "Chuck") -> Map("Tom" -> Set("Susi", "Chuck"))
val g2 = update(g1, "Tom", "Tommy")