在F#中制作循环图.是否需要可变性?

Lay*_*lez 5 f# graph immutability mutability

我想在F#中做一个循环图

我的节点类型看起来像这样:

type Node = { Value : int; Edges : Node list }
Run Code Online (Sandbox Code Playgroud)

我的问题是:为了有周期,我是否需要让Edges可变?

Tom*_*cek 7

F#可以使用循环创建立即的递归对象引用,但这实际上只适用于(相当简单的)记录.所以,如果你在你的定义上尝试这个,它将无法工作:

let rec loop = 
  { Value = 0;
    Edges = [loop] }
Run Code Online (Sandbox Code Playgroud)

但是,你仍然可以避免变异 - 一个合理的选择是使用惰性值:

type Node = { Value : int; Edges : Lazy<Node list>}
Run Code Online (Sandbox Code Playgroud)

这样,您需要为编译器"足够的时间"创建一个loop值,然后才需要评估边缘(并loop再次访问该值):

let rec loop = 
  { Value = 0;
    Edges = lazy [loop] }
Run Code Online (Sandbox Code Playgroud)

在实践中,您可能希望调用一些函数来创建边缘,但这也应该有效.你应该能够写出例如Edges = lazy (someFancyFunction loop).

或者,您也可以使用seq<Edges>(因为序列在默认情况下是惰性的),但每次都会重新评估边缘,因此您可能不希望这样做.