repmin
problem is pretty well-known. We are given a data type for trees:
data Tree a = Leaf a | Fork (Tree a) a (Tree a) deriving Show
We need to write a function down (repmin
) which would take a tree of numbers and replace all numbers in it by their minimum in a single pass. It is also possible to print the tree out along the way (let us say function repminPrint
does this). Both repmin
and pre-, post- and in-order repminPrint
could be written down easily using value recursion. Here is an example for in-order repminPrint
:
import Control.Arrow
replaceWithM :: (Tree Int, Int) -> IO (Tree Int, Int)
replaceWithM (Leaf a, m) = print a >> return (Leaf m, a)
replaceWithM (Fork l mb r, m) = do
(l', ml) <- replaceWithM (l, m)
print mb
(r', mr) <- replaceWithM (r, m)
return (Fork l' m r', ml `min` mr `min` mb)
repminPrint = loop (Kleisli replaceWithM)
But what if we want to write level-order repminPrint
down?
My guess is that we cannot use the queue as we need the ml
and mr
to update the binding for m
. I cannot see how this could be down with a queue. I wrote down an instance for level-order Foldable Tree
to show what I mean:
instance Foldable Tree where
foldr f ini t = helper f ini [t] where
helper f ini [] = ini
helper f ini ((Leaf v) : q = v `f` helper f ini q
helper f ini ((Fork l v r) : q) = v `f` (helper f ini (q ++ [l, r]))
As you can see, we do not run anything on l
and r
during the current recursive call.
So, how could this be done? I would appreciate hints instead of full solutions.