F#unctional Immutable Trie (Prefix Tree) I've created the following implementation of a trie in F# as an effort to learn the language. I would like to know what could be done to make it more idiomatic. Any other pointers are welcome as well.

Of particular interest are: 


Are my tests sufficient? Is there a better way to construct the tests?
Can the logic for insert be made cleaner?
To constrain type or not for functions and parameters?
What remains to be done to classify this as a proper collection?


type Trie&lt;'T when 'T : comparison&gt; = {
    IsTerminal: bool;
    Children: Map&lt;'T, Trie&lt;'T&gt;&gt;;
}

module Trie =
    let empty = {
        IsTerminal = false;
        Children = Map.empty;
    }

    let rec insert branch trie =
        match branch with
        | [] -&gt;
            { trie with IsTerminal = true; }
        | el::els -&gt;
            let child = 
                match Map.tryFind el trie.Children with
                | Some t -&gt; t
                | None -&gt; empty
            let child' = insert els child
            let children =
                if Map.containsKey el trie.Children
                then Map.remove el trie.Children
                else trie.Children
            let children' = Map.add el child' children
            { trie with Children = children' }

    let rec contains branch trie =
        match branch with
        | [] -&gt; trie.IsTerminal
        | el::els -&gt;
            match Map.tryFind el trie.Children with
            | Some t -&gt; contains els t
            | None -&gt; false

    let rec toSeq trie =
        seq {
            for KeyValue(label, trie) in trie.Children do
                if trie.IsTerminal then yield [label]
                let children = toSeq trie
                for child in children do
                    yield label :: child
        }

    module Test =
        let ``insert can insert char into root`` =
            let result = empty |&gt; insert ['a']
            Map.containsKey 'a' result.Children
        do assert ``insert can insert char into root``

        let ``insert can insert char into multiple levels`` =
            let result = empty |&gt; insert ['a'..'d']
            Map.containsKey 'd' (((result.Children |&gt; Map.find 'a').Children |&gt; Map.find 'b').Children |&gt; Map.find 'c').Children
        do assert ``insert can insert char into multiple levels``

        let ``contains finds branches that exist in tree`` =
            let result = empty |&gt; insert ['a'..'d']
            contains ['a'..'d'] result
        do assert ``contains finds branches that exist in tree``

        let ``contains does not find incomplete branches`` =
            let result = empty |&gt; insert ['a'..'d']
            result |&gt; contains ['a'..'c'] |&gt; not
        do assert ``contains does not find incomplete branches``

        let ``contains does not find extended branches`` =
            let result = empty |&gt; insert ['a'..'d']
            result |&gt; contains ['a'..'e'] |&gt; not
        do assert ``contains does not find extended branches``
There are several libraries for writing unit tests in F#. For example:


FsUnit
Unquote
Fuchu


The logic is pretty clear, but there are a couple of comments

1.
Instead of:

        let child = 
            match Map.tryFind el trie.Children with
            | Some t -&gt; t
            | None -&gt; empty


you can rewrite this code with using defaultArg

        let child = 
            Map.tryFind el trie.Children
            |&gt; defaultArg  &lt;| empty


2.
You can use functions from a module Option, so..instead:

        match Map.tryFind el trie.Children with
        | Some t -&gt; contains els t
        | None -&gt; false


better:

        Map.tryFind el trie.Children
        |&gt; Option.exists (contains els)