lue-bird/elm-rosetree-path/2.0.2

NOTE: the latest version is 2.0.5

Tree.Navigate

Additional helpers for a zwilias/elm-rosetree using TreePath

observe

to : TreePath -> Tree label -> Maybe (Tree label)

Following the TreePath, where do we end?

import Tree exposing (tree)
import Tree.Navigate
import Tree.Path


Tree.singleton "jo"
    |> Tree.Navigate.to Tree.Path.atTrunk
--> Just (Tree.singleton "jo")


tree "jo"
    [ Tree.singleton "ann"
    , tree "mic"
        [ Tree.singleton "igg"
        , Tree.singleton "dee"
        , Tree.singleton "bee"
        ]
    ]
    |> Tree.Navigate.to (Tree.Path.follow [ 1, 2 ])
--> Just (Tree.singleton "bee")


tree "jo"
    [ Tree.singleton "ann"
    , tree "mic"
        [ Tree.singleton "igg"
        , Tree.singleton "dee"
        ]
    ]
    |> Tree.Navigate.to (Tree.Path.follow [ 1, 2 ])
--> Nothing

altering

map :
( { path : TreePath
, label : label
}
-> mappedLabel
)
-> Tree label
-> Tree mappedLabel

Change every label based on its TreePath and current value.

import Tree exposing (tree)
import Tree.Navigate
import Tree.Path


tree 1
    [ Tree.singleton 2
    , tree 3 [ Tree.singleton 4 ]
    , Tree.singleton 5
    ]
    |> Tree.Navigate.map
        (\n -> ( n.label * 2, n.path ))
--> tree ( 2, Tree.Path.atTrunk )
-->     [ Tree.singleton ( 4, Tree.Path.follow [ 0 ] )
-->     , tree ( 6, Tree.Path.follow [ 1 ] )
-->         [ Tree.singleton ( 8, Tree.Path.follow [ 1, 0 ] ) ]
-->     , Tree.singleton ( 10, Tree.Path.follow [ 2 ] )
-->     ]




tree 0 [ Tree.singleton 1, tree 2 [ Tree.singleton 3 ], Tree.singleton 5 ]
    |> Tree.Navigate.map identity
    |> Tree.flatten
--> [ { label = 0, path = Tree.Path.atTrunk }
--> , { label = 1, path = Tree.Path.follow [ 0 ] }
--> , { label = 2, path = Tree.Path.follow [ 1 ] }
--> , { label = 3, path = Tree.Path.follow [ 1, 0 ] }
--> , { label = 5, path = Tree.Path.follow [ 2 ] }
--> ]
alter : TreePath -> (Tree a -> Tree a) -> Tree a -> Tree a

Change its sub-tree at a given TreePath based on its current value.

import Tree exposing (tree)
import Tree.Navigate
import Tree.Path


tree "jo"
    [ Tree.singleton "ann"
    , tree "mic"
        [ Tree.singleton "igg"
        , Tree.singleton "dee"
        , Tree.singleton "bee"
        ]
    ]
    |> Tree.Navigate.alter (Tree.Path.follow [ 1, 2 ])
        (Tree.mapLabel String.toUpper)
--> tree "jo"
-->     [ Tree.singleton "ann"
-->     , tree "mic"
-->         [ Tree.singleton "igg"
-->         , Tree.singleton "dee"
-->         , Tree.singleton "BEE"
-->         ]
-->     ]


tree "jo"
    [ Tree.singleton "ann"
    , tree "mic"
        [ Tree.singleton "igg"
        , Tree.singleton "dee"
        ]
    ]
    |> Tree.Navigate.alter (Tree.Path.follow [ 1, 2 ])
        (Tree.mapLabel String.toUpper)
--> tree "jo"
-->     [ Tree.singleton "ann"
-->     , tree "mic"
-->         [ Tree.singleton "igg"
-->         , Tree.singleton "dee"
-->         ]
-->     ]

transform

( { path : TreePath
, label : label
, children : List folded
}
-> folded
)
-> Tree label
-> folded

A powerful tree transformation which can be described as "replacing the tree node constructors"

invertTree : Tree label -> Tree label
invertTree =
    Tree.Navigate.restructure (\sub -> tree sub.label (sub.children |> List.reverse))


toPreOrder : Tree label -> List label
toPreOrder =
    Tree.Navigate.restructure (\sub -> sub.label :: (sub.children |> List.concat))


type DifferentTree a
    = DifferentTree a (List (DifferentTree a))


toDifferentTree : Tree label -> DifferentTree label
toDifferentTree =
    Tree.Navigate.restructure (\sub -> DifferentTree sub.label sub.children)

Other names for this pattern are "unwrap", "fold" and "banana" Resources I can recommend:

Additionally, you get the TreePath at each step. Check the readme for how this can be useful.