将一个懒惰的图形变成一个没有变异的严格图形 - OCaml

时间:2017-11-15 19:05:32

标签: ocaml

假设我有一个(定向)图表,其中包含

类型的节点
type lazy_node_t = LazyNode of int * lazy_node_t Lazy.t list;;

其中第一个int是任意标记,列表是可从当前节点访问的延迟节点列表。

我有什么方法可以将其转换为type node_t = Node of int * node_t list的图形而不使用任何可变值?例如,我意识到使用数组是可能的。

谢谢!

3 个答案:

答案 0 :(得分:2)

如果可以将名称绑定到结果中的所有节点,则可以使用let rec创建循环结构。对于一般情况,您不能为所有节点指定名称。因此没有办法在没有可变性的情况下制作循环结构。至少,这是我的结论。

答案 1 :(得分:1)

我不知道你为什么要避免可变值,但我认为原因暗示效率不是问题。

原则上,您可以将使用可变值的任何算法转换为不使用可变值的算法。特别是对于数组,您可以使用Map.Make(Int).t代替Intstruct type t=int let compare=compare end

更新:

只是为了澄清:根据我的想法,模块Int中的整数与图标签没有任何关系。它们是替换阵列的索引。

我的回答是基于这样的假设,即您只需将数组作为中间结构。也就是说,您可以使用输出所需类型node_t = Node of int * node_t list的数组的解决方案。杰弗里斯科菲尔德的回答表明我可能误解了;您只有一个输出类型node_t = Node of int * node_t array的解决方案。在那种情况下,我的回答没有帮助。

答案 2 :(得分:1)

根据我对你问题的第二种解释,第二个答案。

有一种方法,但它很难看。我们必须使用稍微不同的类型:

type node_immutable = {
  tag_immutable : int;
  out_neighbours_immutable : node_immutable list;
}

然后,我们利用可变性对值的内部表示没有影响的事实。所以下面的类型

type node_mutable = {
  mutable tag_mutable : int;
  mutable out_neighbours_mutable : node_mutable list;
}

在内部与node_immutable无法区分。所以我们可以像这样创建一个图形的可变版本:

let rec mutable_node1 = {tag_mutable=1; out_neighbours_mutable=[mutable_node2];}
  and mutable_node2 = {tag_mutable=2; out_neighbours_mutable=[mutable_node3];}
  and mutable_node3 = {tag_mutable=3; out_neighbours_mutable=[mutable_node1];}

然后通过编组创建一个不可变的副本:

let node1 = (
  Marshal.from_string (Marshal.to_string mutable_node1 []) 0
  : node_immutable)