簡體   English   中英

F#中的遞歸和不變性

[英]Recursion & Immutability in F#

請考慮以下簡單示例:

type Parent = { Children : Child list }
and Child = { Value : int ; Parent : Parent }

let rec children = [ { Value = 0 ; Parent = parent } ]
and parent = { Children = children }

F#編譯器非常智能,可以正確初始化這些遞歸對象,可以通過運行驗證

obj.ReferenceEquals(parent, parent.Children.Head.Parent)

現在,考慮以下概括:

let length = 100 // assume arbitrary

let rec children = List.init length (fun i -> { Value = i ; Parent = parent })
and parent = { Children = children }

此定義將導致編譯器錯誤。 我的問題如下:有沒有辦法在訴諸反射或可變字段的情況下進行上述綁定?

let rec mkChild i = {Value = i; Parent = parent}
and parent = { Children = children }
and children = List.init length mkChild

我無法回答F# ,但我確信在OCaml中沒有辦法做到這一點,這與F#非常接近。 這與定義循環列表相同:

let rec a = 1 :: 2 :: a;

在遞歸對象定義的情況下,您不能在遞歸循環中進行函數調用,因為它意味着在尚未完全構造的對象上調用函數。

更確切地說,在您的示例中,您正嘗試向List.init傳遞一個閉包(fun i -> { Value = i ; Parent = parent })但是由於parent尚未完全定義,因此無法定義此閉包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM