1 -----------------------------------------------------------------------------
4 -- Copyright : (c) The University of Glasgow 2002
5 -- License : BSD-style (see the file libraries/base/LICENSE)
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : portable
11 -- Multi-way trees (/aka/ rose trees) and forests.
13 -- Also included are neat presentations for trees and forests.
15 -----------------------------------------------------------------------------
22 -- | Multi-way trees, also known as /rose trees/.
23 data Tree a = Node a (Forest a) -- ^ a value and zero or more child trees.
24 type Forest a = [Tree a]
26 instance Functor Tree where
29 mapTree :: (a -> b) -> (Tree a -> Tree b)
30 mapTree f (Node x ts) = Node (f x) (map (mapTree f) ts)
32 instance Show a => Show (Tree a) where
34 showList ts s = showForest ts ++ s
36 showTree :: Show a => Tree a -> String
37 showTree = drawTree . mapTree show
39 showForest :: Show a => Forest a -> String
40 showForest = unlines . map showTree
42 drawTree :: Tree String -> String
43 drawTree = unlines . draw
45 draw :: Tree String -> [String]
46 draw (Node x ts0) = grp this (space (length this)) (stLoop ts0)
47 where this = s1 ++ x ++ " "
49 space n = replicate n ' '
52 stLoop [t] = grp s2 " " (draw t)
53 stLoop (t:ts) = grp s3 s4 (draw t) ++ [s4] ++ rsLoop ts
55 rsLoop [] = error "rsLoop:Unexpected empty list."
56 rsLoop [t] = grp s5 " " (draw t)
57 rsLoop (t:ts) = grp s6 s4 (draw t) ++ [s4] ++ rsLoop ts
59 grp fst0 rst = zipWith (++) (fst0:repeat rst)
61 [s1,s2,s3,s4,s5,s6] = ["- ", "--", "-+", " |", " `", " +"]
63 -- | The elements of a tree in pre-order.
64 flatten :: Tree a -> [a]
65 flatten t = squish t []
66 where squish (Node x ts) xs = x:foldr squish xs ts
68 -- | Lists of nodes at each level of the tree.
69 levels :: Tree a -> [[a]]
70 levels t = map (map root) $ takeWhile (not . null) $ iterate subforest [t]
71 where root (Node x _) = x
72 subforest f = [t | Node _ ts <- f, t <- ts]