Ocaml 如何在不使用可变数据的情况下创建具有循环的图?

Ocaml 如何在不使用可变数据的情况下创建具有循环的图?,ocaml,immutability,mutual-recursion,Ocaml,Immutability,Mutual Recursion,我有下一个代码: module MakeLink (Key : Map.OrderedType) = struct module Links = Map.Make (Key) type 'a t = { links : 'a t Links.t; value : 'a } type key_t = Key.t let make value = { links = Links.empty;

我有下一个代码:

module MakeLink (Key : Map.OrderedType) = struct
   module Links = Map.Make (Key)

    type 'a t = 
      { links : 'a t Links.t;
        value : 'a
      }

    type key_t = Key.t

    let make value = 
      { links = Links.empty;
        value
      }

    let link linker ~to':linkable ~by:key = 
      { linker with links = 
        Links.add key linkable linker.links
      } 

   (* some functions for reading here *)
end
如何创建相互链接的两个链接? 我试过:

let join a ~with':b ~by:key = 
  let rec a' = link a ~to':b' ~by:key
      and b' = link b ~to':a' ~by:(Key.opposite key) in
  a'

我的问题是:如何使用(OCaml或其他语言)在没有可变数据的情况下创建具有循环的图形(例如:双链表)?

您可以使用
let rec
在OCaml中创建循环链接结构

# type 'a g = { links: 'a g list; value: 'a };;
type 'a g = { links : 'a g list; value : 'a; }
# let rec a = { links = [b]; value = 5; }
      and b = { links = [a]; value = 6; };;
val a : int g =
  {links =
  ... many strange lines of output ...
val b : int g =
  {links =
  ... many more strange lines of output ...
然而,一旦有了这样的结构,就很难编写能够以有用的方式处理它的函数。我不认为你能用OCaml,一种渴望的语言来做这种编程。实际上,您必须为链接使用可变字段


我没有这方面的经验,但似乎更可能用Haskell(一种非渴望的语言)进行这种处理。

这在OCaml中是可能的,但是需要过多的代码重复。如果看到一些代码只需要一个简单的周期和一个新元素,然后返回一个新的周期并添加元素,那就太酷了。您可以通过在单独的数据结构(通常是一个矩阵,它可能是可变的,也可能不是可变的,尽管前者的性能更好)、使用和映射中移动链接来缓解这个问题(如果ID是整数,则仅使用数组)从节点ID到节点数据。以这种方式拆分数据的另一个优点是,您可以轻松地调整现有算法并将其应用到图形中。使用数组还可以更好地使用缓存局部性。