I've been working on a rough idea for a templating engine (mostly as a learning project) using the F# syntax. How correct is my code in terms of being idiomatic F#? Are there F# features which would make the code simpler? More easily understood? The template files are loaded at runtime using a script I've not posted here The code is also provided as a gist for easier reading.Template#r program.exeopen Systemopen Liblet intToText i = div [] [Text((sprintf I is %i i))]Template (    html [] [        div [(id, 123);(class, me)] [            div [] [                   Text SOME TEXT            ]            div [] [                Text SOME MORE TEXT            ]            foreach [1;2;3] intToText            input [(type, text); (value, 1)]        ]    ])Libmodule Libopen Systemopen System.Texttype Attributes = (string * string) listtype Element =    | Tag of (string * Attributes * Element list)    | TagSelfClosing of (string * Attributes)    | Collection of (Element list)    | Text of stringlet html (attrs:Attributes) el:Element = Tag(html, attrs, el)let div (attrs:Attributes) el:Element = Tag(div, attrs, el)let input (attrs:Attributes) = TagSelfClosing(input, attrs)let foreach data fn =     let elems = data |> List.map fn    Collection(elems)type Token =     | OPEN_TAG of (string * Attributes)    | CLOSE_TAG of string    | SELF_CLOSING_TAG of (string * Attributes)    | TEXT of string let Template el =    let rec expandTree el output =         match el with        | Tag(tagName, attrs, children) ->             let childContent =                 children                |> List.fold (fun state item -> state @ (expandTree item [])) []            let addition = [OPEN_TAG(tagName, attrs)]@childContent@[CLOSE_TAG(tagName)]            output@addition        | TagSelfClosing(tagName, attrs) ->            let addition = [SELF_CLOSING_TAG(tagName, attrs)]            output@addition        | Collection(elements) ->            let collectionContent =                elements                |> List.map (fun e -> expandTree e output)                |> List.fold (fun state item -> state@item) []            output @ collectionContent        | Text(string) ->            output@[TEXT(string)]    let tokenWriter token =         let attributeWriter (tuple:string*string) =            let (name, value) = tuple            sprintf  %s=\%s\ name value        let foldAttributes attrs =            attrs            |> List.map attributeWriter            |> List.fold (fun state item -> state+item)          match token with        | OPEN_TAG(name, attrs) ->             let attributes = foldAttributes attrs            sprintf <%s%s> name attributes        | CLOSE_TAG(name) -> sprintf </%s> name        | SELF_CLOSING_TAG(name, attrs) ->             let attributes = foldAttributes attrs            sprintf <%s%s /> name attributes        | TEXT(content) -> sprintf %s content     let expandedTree = expandTree el []    let content =         expandedTree         |> List.map tokenWriter         |> List.fold (fun state item -> state+item)     printf %s content
Basic templating engine in F# using F# syntax
f#;template meta programming
There are a few suggestions which immediately occur to me:  some are minor changes which could improve the clarity of the code and there is one major change which would shorten the code quite a bit.The minor changes:For List.fold you can just pass a function which matches the expected type and not write the full lambda.  With an operator like + it's not obvious, but you can clean up your code a bit using:attrs|> List.map (fun (name,value) -> sprintf %s=\%s\ name value)|> List.fold (+) In the function childContent, I would move the call to expandTree into a List.map, to reduce the amount of nesting and to allow us to clean up the List.fold:children|> List.map (fun child -> expandTree child [])|> List.fold (@) []With Text(string) you should use a name other than string since that's the name of an existing type and that could cause confusion for someone reading your code.The major change is that you can combine the tokenWriter and the expandTree into a single function.  At the heart, what you are doing is an in order traversal of a tree to convert your HTML structure into a string:  expandTree does an in order traversal to flatten the tree into a list and then tokenWriter converts those tokens into strings.  You're not gaining much by flattening the tree and then generating the output string; so, you could just use the tree traversal to generate the output string.Making this change also allows you to remove the Token type, further reducing the overall complexity of your code.Here's the updated code:    let Template el =        let rec elementToString el output =             let attributesToString attrs =                attrs                |> List.map (fun (name,value) -> sprintf %s=\%s\ name value)                |> List.fold (+)             match el with            | Tag(tagName, attrs, children) ->                 let attributes = attributesToString attrs                let tagStr = sprintf <%s%s> tagName attributes                let childContent =                     children                    |> List.map (fun item -> elementToString item  )                    |> List.fold (+) tagStr                let closeTagStr = sprintf </%s> tagName                sprintf %s%s%s output childContent closeTagStr            | TagSelfClosing(tagName, attrs) ->                let attributes = attributesToString attrs                sprintf %s<%s%s /> output tagName attributes            | Collection(elements) ->                elements                |> List.map (fun e -> elementToString e output)                |> List.fold (+)             | Text(text) ->                sprintf %s%s output text        let expandedTree = elementToString el         let content =             expandedTree        printf %s content