Lay*_*lez 5 f# graph immutability mutability
我想在F#中做一个循环图
我的节点类型看起来像这样:
type Node = { Value : int; Edges : Node list }
Run Code Online (Sandbox Code Playgroud)
我的问题是:为了有周期,我是否需要让Edges可变?
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>
(因为序列在默认情况下是惰性的),但每次都会重新评估边缘,因此您可能不希望这样做.