For two multi-way trees, t1 and t2, defined using
type Forest a = [Tree a]
data Tree a = Node {
rootLabel :: a,
subForest :: Forest a
}
how can I write a function that will remove a subtree from t1 and insert it at a given node in t2?
I imagine the signature would look something like
moveSubTree :: ((Tree x a) x (Tree x a)) -> (Tree x Tree)
i.e. it takes a tree and parent node defining a subtree to be removed, and a second tree and node that defines the point at which to insert the original subtree.
Separate functions to remove and then add the subtree could be composed if necessary.
You can make edits and reads "at a path" in a tree.
data Dir = L | R
type Path = [Dir]
data Tree a = Leaf | Node a (Tree a) (Tree a)
read :: Path -> Tree a -> Maybe (Tree a)
read [] t = t
read (s:ss) t = case t of
Leaf -> Nothing
Node a l r -> case s of
L -> read ss l
R -> read ss r
edit :: Path -> (Tree a -> Tree a) -> Tree a -> Maybe (Tree a)
edit [] f t = Just (f t)
edit (s:ss) f t = case t of
Leaf -> Nothing
Node a l r -> case s of
L -> do
l' <- edit ss f l
return (Node a l' r)
R -> do
r' <- edit ss f r
return (Node a l r')
And then using this tool you can "copy and paste" subtrees from one path to another
cnp :: Path -> Path -> Tree a -> Maybe (Tree a)
cnp readPath writePath t = do
subtree <- read readPath t
edit writePath (const subtree) t
Interestingly, "subtree at path" forms a Lens
which subsumes the common structure between these two operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With