maca / elm-rose-tree / RoseTree.Tree


type Tree a
    = Tree a (Array (Tree a))

Represents a tree where each node contains a value of type a and an array of zero or more children.

tree : Tree String
tree =
    Tree "root" (Array.fromList [ Tree "a" (Array.fromList []) ])

Create

branch : a -> List (Tree a) -> Tree a

Creates a branch node with the given value and children.

branch "root" [ leaf "a" ]
    == Tree "root" (Array.fromList [ Tree "a" (Array.fromList []) ])

leaf : a -> Tree a

Creates a leaf node with the given value.

 leaf 42 == Tree 42 (Array.fromList [])

Traversing and updating

get : List Basics.Int -> Tree a -> Maybe (Tree a)

Retrieves a child node at the specified path.

 get [ 1, 0 ] (branch "root" [ leaf "a", branch "b" [ leaf "z" ] ])
     == Just (leaf "z")

updateAt : List Basics.Int -> (Tree a -> Tree a) -> Tree a -> Tree a

Updates a child node at the specified path using a function if the node exists.

updateAt [ 1 ] (updateValue ((*) -1)) (branch 0 [ leaf 1, leaf 2 ])
    == branch 0 [ leaf 1, leaf -2 ]

replaceAt : List Basics.Int -> Tree a -> Tree a -> Tree a

Replaces a child node at the specified path with a new node if the node exists.

replaceAt [ 1 ] (leaf "new") (branch "root" [ leaf "a", leaf "old" ])
    == branch "root" [ leaf "a", leaf "new" ]

removeAt : List Basics.Int -> Tree a -> Tree a

Removes a child node at the specified path.

removeAt [ 1, 0 ]
    (branch "root" [ leaf "a", branch "b" [ leaf "z" ] ])
    == branch "root" [ leaf "a", leaf "b" ]

insertBefore : List Basics.Int -> Tree a -> Tree a -> Tree a

Inserts a new node before a child node at the specified path.

insertBefore [ 1 ] (leaf "new") (branch "root" [ leaf "a", leaf "b" ])
    == branch "root" [ leaf "a", leaf "new", leaf "b" ]

insertAfter : List Basics.Int -> Tree a -> Tree a -> Tree a

Inserts a new node after a child node at the specified path.

insertAfter [ 0 ] (leaf "new") (branch "root" [ leaf "a", leaf "b" ])
    == branch "root" [ leaf "a", leaf "new", leaf "b" ]

Properties

value : Tree a -> a

Retrieves the value of a tree node.

 value (leaf "leaf") == "leaf"

setValue : a -> Tree a -> Tree a

Sets the value of a tree node.

 setValue "new" (leaf "old") == leaf "new"

updateValue : (a -> a) -> Tree a -> Tree a

Updates the value of a tree node using a function.

 updateValue String.toUpper (leaf "value") == leaf "VALUE"

getValueAt : List Basics.Int -> Tree a -> Maybe a

Retrieves the value of a child node at the specified path.

 getValueAt [ 1, 0 ] (branch "root" [ leaf "a", branch "b" [ leaf "z" ] ])
     == Just "z"

updateValueAt : List Basics.Int -> (a -> a) -> Tree a -> Tree a

Updates the value for a child node at the specified path using a function.

updateValueAt [ 1 ] String.toUpper (branch "root" [ leaf "a", leaf "b" ])
    == branch "root" [ leaf "a", leaf "B" ]

Children

children : Tree a -> List (Tree a)

Retrieves the immediate children of a tree node.

children (branch "root" [ leaf "a", leaf "b" ])
    == [ leaf "a", leaf "b" ]

unshift : Tree a -> Tree a -> Tree a

Adds a child node to the beginning of the children list of a parent node.

unshift (leaf "b") (branch "root" [ leaf "a" ])
    == branch "root" [ leaf "b", leaf "a" ]

push : Tree a -> Tree a -> Tree a

Adds a child node to the end of the children list of a parent node.

push (leaf "b") (branch "root" [ leaf "a" ])
    == branch "root" [ leaf "a", leaf "b" ]

pushChildFor : List Basics.Int -> Tree a -> Tree a -> Tree a

Adds a child node to the end of the children list of a parent node at a path.

pushChildFor [ 0 ] (leaf "x") (branch "root" [ branch "a" [ leaf "b" ] ])
    == branch "root" [ branch "a" [ leaf "b", leaf "x" ] ]

unshiftChildFor : List Basics.Int -> Tree a -> Tree a -> Tree a

Adds a child node to the beginning of the children list of a parent node at a path.

unshiftChildFor [ 0 ] (leaf "x") (branch "root" [ branch "a" [ leaf "b" ] ])
    == branch "root" [ branch "a" [ leaf "x", leaf "b" ] ]

Folds

map : (Tree a -> Tree a) -> Tree a -> Tree a

Applies a transformation function to each node in the tree.

 map (updateValue ((+) 1)) (branch 0 [ leaf 1, branch 2 [ leaf 3 ] ])
     == branch 1 [ branch 2 [], branch 3 [ leaf 4 ] ]

mapValues : (a -> b) -> Tree a -> Tree b

Applies a value transformation function to the values of each node in the tree.

mapValues ((*) 2) (branch 0 [ leaf 1, branch 2 [ leaf 3 ] ])
    == branch 0 [ branch 2 [], branch 4 [ leaf 6 ] ]

map (updateValue ((*) 2)) (leaf 0) == mapValues ((*) 2) (leaf 0)

filterMap : (Tree a -> Maybe (Tree a)) -> Tree a -> Tree a

Applies a filter and transformation function to each node in the tree. Nodes for which the filter returns Nothing are removed, and nodes for which the filter returns Just are replaced with the transformed value.

filterMap
    (\node ->
        if value node == "b" then
            Just (setValue "x" node)

        else
            Nothing
    )
    (branch "root" [ leaf "a", branch "b" [ leaf "z" ] ])
    == branch "root" [ leaf "x" ]

foldl : (Tree a -> b -> b) -> b -> Tree a -> b

Reduces a tree from the deepest rightmost.

 foldl (\n acc -> value n ++ acc) "" (branch "a" [ leaf "b", leaf "c" ])
     == "cba"

foldr : (Tree a -> b -> b) -> b -> Tree a -> b

Reduces a tree from the deepest leftmost.

 foldr (\n acc -> value n ++ acc) "" (branch "a" [ leaf "b", leaf "c" ])
     == "bca"

findl : (Tree a -> Basics.Bool) -> Tree a -> Maybe (Tree a)

Finds the first node in the tree that satisfies a predicate function straring from the deepest leftmost node.

 findl (\n -> value n > 1) (branch 0 [ branch 1 [ leaf 0, leaf 2, leaf 3 ] ])
     == Just (leaf 2)

findr : (Tree a -> Basics.Bool) -> Tree a -> Maybe (Tree a)

Finds the first node in the tree that satisfies a predicate function straring from the deepest rightmost node.

 findr (\n -> value n > 1) (branch 0 [ branch 1 [ leaf 0, leaf 2, leaf 3 ] ])
     == Just (leaf 3)

any : (Tree a -> Basics.Bool) -> Tree a -> Basics.Bool

Checks if any node in the tree satisfies a predicate function.

any (\n -> value n == "b") (branch "root" [ leaf "a", leaf "b" ]) == True

all : (Tree a -> Basics.Bool) -> Tree a -> Basics.Bool

Checks if all nodes in the tree satisfy a predicate function.

all (\n -> value n > 1) (branch 2 [ leaf 3, leaf 4 ]) == True

foldWithPath : (List Basics.Int -> Tree a -> b -> b) -> b -> Tree a -> b

Reduces a tree from the deepest leftmost, passing the path as the first argument to the reducer, and omitting the root.

Folding to a list will make for a weird order ;)

foldWithPath (\p n acc -> ( value n, p ) :: acc) [] (branch "a" [ leaf "b", leaf "c" ])
    == [ ( "c", [ 1 ] ), ( "b", [ 0 ] ) ]