Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating recursive discriminated unions values

When I have this code:

type HtmlNode = 
    | HtmlElement of name:string * attribute:HtmlAttribute list
    | HtmlText of content:string

and HtmlAttribute =  
    | HtmlAttribute of name:string * value:string * parent:HtmlNode

let createElement name attrs =
    let toAttributes element = [ for name, value in attrs -> HtmlAttribute(name, value, element)]
    let rec element = HtmlElement(name, attributes)
    and attributes = toAttributes element
    element

The compiler gives the following error:

Recursive values cannot appear directly as a construction of the type 'HtmlNode' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.

Why is that? The let rec is supposed to support the creation of recursive values, and something similar works with records.

like image 985
Gustavo Guerra Avatar asked Nov 01 '22 00:11

Gustavo Guerra


1 Answers

I don't know why this was changed, but one workaround is to use seq instead of list.

type HtmlNode = 
    | HtmlElement of name:string * attribute:HtmlAttribute seq
    | HtmlText of content:string

and HtmlAttribute =  
    | HtmlAttribute of name:string * value:string * parent:HtmlNode

let createElement name attrs =
    let rec element = HtmlElement(name, attributes)
    and attributes = seq { for name, value in attrs -> HtmlAttribute(name, value, element) }
    element
like image 130
Daniel Avatar answered Nov 09 '22 05:11

Daniel