Additional helpers for a zwilias/elm-rosetree
using TreePath
to : Tree.Path.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
map : ({ path : Tree.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 : Tree.Path.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"
--> ]
--> ]
restructure : ({ path : Tree.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.