假设我有一个(定向)图表,其中包含
类型的节点type lazy_node_t = LazyNode of int * lazy_node_t Lazy.t list;;
其中第一个int
是任意标记,列表是可从当前节点访问的延迟节点列表。
我有什么方法可以将其转换为type node_t = Node of int * node_t list
,的图形而不使用任何可变值?例如,我意识到使用数组是可能的。
谢谢!
答案 0 :(得分:2)
如果可以将名称绑定到结果中的所有节点,则可以使用let rec
创建循环结构。对于一般情况,您不能为所有节点指定名称。因此没有办法在没有可变性的情况下制作循环结构。至少,这是我的结论。
答案 1 :(得分:1)
我不知道你为什么要避免可变值,但我认为原因暗示效率不是问题。
原则上,您可以将使用可变值的任何算法转换为不使用可变值的算法。特别是对于数组,您可以使用Map.Make(Int).t
代替Int
为struct 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)