Given, for example, the following tree data type:
data Tree a = Node [Tree a] | Leaf a deriving Show
type Sexp = Tree String
How do I express a "pretty" function using an high-order combinator, that prints the tree with proper indentation? For example:
sexp =
Node [
Leaf "aaa",
Leaf "bbb",
Node [
Leaf "ccc",
Leaf "ddd",
Node [
Leaf "eee",
Leaf "fff"],
Leaf "ggg",
Leaf "hhh"],
Leaf "jjj",
Leaf "kkk"]
pretty = ????
main = print $ pretty sexp
I want the result of that program to be:
(aaa
bbb
(ccc
ddd
(eee
fff)
ggg
hhh)
jjj
kkk)
Here is an incomplete solution, using a "fold" as the combinator, that doesn't implement the indentation:
fold f g (Node children) = f (map (fold f g) children)
fold f g (Leaf terminal) = g terminal
pretty = fold (\ x -> "(" ++ (foldr1 ((++) . (++ " ")) x) ++ ")") show
main = putStrLn $ pretty sexp
It is obviously not possible to write the function I want using fold
, since it forgets the tree structure. So, what is a proper high-order combinator that is generic enough to allow me to write the function I want, but less powerful than writing a direct recursive function?