Consider the following definition of a tree:
data Tree a = Leaf a | Node [Tree a]
And a sample tree:
input :: Tree String
input = Node [Leaf "a", Leaf "b", Node [Leaf "c", Leaf "d"]]
I'm trying to 'map' a list over such a tree, whereas the values of the tree should be discarded. In the case of [0..]
being the list, the result should look like:
output :: Tree Int
output = Node [Leaf 0, Leaf 1, Node [Leaf 2, Leaf 3]]
So I'm looking for a function..
seqTree :: [b] -> Tree a -> Tree b
seqTree = undefined
.. for which the following holds:
seqTree [0..] input == output
I came to the conclusion that a function like this must wrap another function in order to keep track of list items which has not been 'taken' yet:
seqTree' :: [b] -> Tree a -> Tree ([b], b)
seqTree' xxs@(x:xs) t = case t of
Leaf _ -> Leaf (xs, x)
--Node ts = the tricky part... maybe something with foldr?
seqTree' [] t = error "empty list."
With this I was hoping to implement seqTree
, which would require some final mapping over the whole tree, I guess there are better ways to do this, here is a verbose version:
finish :: Tree (a,b) -> Tree b
finish t = case t of
Leaf v -> Leaf $ snd v
Node ts -> Node (map finish ts)
And finally:
seqTree xs t = finish $ seqTree' xs t
This compiles, however as marked with the comment, the function seqTree'
is partial. Does anybody know how to fix this, and furthermore, what would be a more appropriate, less low level approach for solving this?