Suppose u has the following recursive record type
type Parent = { Name : string Age : int Children : Child list } and Child = { Name : string Parent : Parent option }
I can easily instantiate with
module Builder = let create name kids = let rec makeChild kid = { kid with Parent = parent |> Some } and parent = { Name = name Age = 42 Children = children } and children = kids |> List.map makeChild parent let createChild name = { Child.Name = name; Parent = None }
But when I try to "transform" an existing adult into a parent, using "c" as follows:
module Builder2 = let createAdult name age = { Parent.Name = name; Age = age; Children = [] } let create name kids = let rec makeChild kid = { kid with Parent = parent |> Some } and parent = { (createAdult name 42) with Children = children } and children = kids |> List.map makeChild parent let createChild name = { Child.Name = name; Parent = None }
I get:
error FS0040: this and other recursive references to the designated object will be checked for reliable initialization at runtime using a slow link. This is because you are defining one or more recursive objects, not recursive functions. This warning can be suppressed using "#nowarn" 40 "or" --nowarn: 40 ".
and "Children = children" in the "parent" definition are highlighted.
What am I doing wrong?
Edit:
Another point: when I move the "Builder" (which worked) to another assembly (for example, a test assembly), it immediately stops working with:
error FS0261: Recursive values โโcannot be directly bound to a non-variable field "Children" of type "Parent" in a recursive binding. Instead, consider using a mutable field.
Edit: Based on the comments I tried
let create name kids = let rec makeChild kid = { kid with Parent = parent |> Some } and adult = createAdult name 42 and parent = { adult with Children = children } and children = kids |> List.map makeChild
but still no luck - the compiler still does not see this utility, similar to the working one: (