F # преобразовать список в дерево

У меня есть список кортежей int * string, где int это уровень, а string это имя

let src = [
        (0, "root");
            (1, "a");
                (2, "a1");
                (2, "a2");
            (1, "b");
                (2, "b1");
                    (3, "b11");
                (2, "b2");
        ]

и мне нужно преобразовать его в следующий

let expectingTree = 
    Branch("root", 
    [
        Branch("a",
            [
                Leaf("a1");
                Leaf("a2")
            ]);
        Branch("b",
            [
                Branch("b1", [Leaf("b11")]);
                Leaf("b2")
            ]);
    ]);

Ниже приведен способ, как я это сделал, но кто-нибудь может посоветовать лучший способ добиться этого. Я новичок в F #, и код C #, чтобы сделать то же самое, был бы немного короче, так что, я думаю, я ошибаюсь.

type Node = 
    | Branch of (string * Node list)
    | Leaf of string

let src = [
            (0, "root");
                (1, "a");
                    (2, "a1");
                    (2, "a2");
                (1, "b");
                    (2, "b1");
                        (3, "b11");
                    (2, "b2");
            ]

let rec setParents (level:int) (parents:list<int>) (lst:list<int*int*string>) : list<int*int*string> =
    //skip n items and return the rest
    let rec skip n xs = 
        match (n, xs) with
        | n, _ when n <= 0 -> xs
        | _, [] -> []
        | n, _::xs -> skip (n-1) xs

    //get parent id for given level
    let parentId (level) = 
        let n = List.length parents - (level + 1)
        skip n parents |> List.head 

    //create new parent list and append new id to begin
    let newParents level id =
        let n = List.length parents - (level + 1)
        id :: skip n parents

    match lst with
    | (id, l, n) :: tail -> 
                        if l = level then (id, parentId(l), n) :: setParents l (newParents l id) tail
                        elif l <= level + 1 then setParents l parents lst
                        else [] //items should be in order, e.g. there shouldnt be item with level 5 after item with level 3
    | _ -> []


let rec getTree (root:int) (lst: list<int*int*string>) =

    let getChildren parent = 
        List.filter (fun (_, p, _) -> p = parent) lst

    let rec getTreeNode (id:int) (name:string) =
        let children = getChildren id
        match List.length children with
        | 0 -> Leaf(name)
        | _ -> Branch(name, 
                        children
                        |> List.map (fun (_id, _, _name) -> getTreeNode _id _name))

    match getChildren root with
    | (id, _, n) :: _ -> getTreeNode id n
    | _ -> Leaf("")

let rec printTree (ident:string) (tree:Node) = 
    match tree with
    | Leaf(name) -> 
        printfn "%s%s" ident name
    | Branch(name, children) -> 
        printfn "%s%s" ident name
        List.iter (fun (node) -> printTree ("   " + ident) node) children

let tree = 
    src
    |> List.mapi (fun i (l, n) -> (i+1, l, n)) //set unique id to each item
    |> setParents 0 [0] //set parentId to each item
    |> getTree 0


printTree "" tree

Console.ReadKey() |> ignore

Ответы на вопрос(1)

Ваш ответ на вопрос