F # allows you to create immediate recursive references to objects with loops, but it really only works on (fairly simple) records. So, if you try this by your definition, this will not work:
let rec loop = { Value = 0; Edges = [loop] }
However, you can still avoid the mutation - one reasonable alternative is to use lazy values:
type Node = { Value : int; Edges : Lazy<Node list>}
Thus, you give the compiler “enough time” to create the loop value before it needs to evaluate the edges (and get the loop value again):
let rec loop = { Value = 0; Edges = lazy [loop] }
In practice, you probably want to call some functions to create edges, but this should work too. You should be able to write, for example. Edges = lazy (someFancyFunction loop) .
Alternatively, you can also use seq<Edges> (since the default values are lazy), but this will repeat the edge evaluation every time, so you probably won't want to do this.
source share