2014-05-01 11 views
5

Quando ho questo codice:Creazione sindacati discriminati ricorsive valori

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 

Il compilatore dà il seguente errore:

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.

Perché? Il let rec dovrebbe supportare la creazione di valori ricorsivi e qualcosa di simile funziona con i record.

+0

Non riesco a ottenere un errore con questo. – eulerfx

+0

In base al messaggio, questo è stato probabilmente modificato nella versione 3.1 più recente. – Daniel

+0

Lo stesso errore si verifica in F # 3.0, quindi è leggermente più vecchio –

risposta

2

Non so perché questo è stato modificato, ma una soluzione alternativa è utilizzare seq anziché 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 
+0

Interessante, se faccio passare una lista o un array al seq, si blocca in fase di esecuzione –

+0

Ho notato anche questo. Sembra che sia richiesto un livello di riferimento indiretto. – Daniel