Search code examples
haskellpretty-print

How does one pretty print recursion depth in Haskell?


Let's say I have a binary tree.

main = putStrLn $ printTree tree                                                                                                                                                                                

data Tree = Empty | Node Int (Tree) (Tree) deriving (Show)                                                                                                                                                      

tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty                                                                                                                                                         

printTree :: Tree -> String                                                                                                                                                                                     
printTree x = case x of                                                                                                                                                                                         
  Node num treeA treeB -> show num ++ "\n" ++ printTree treeA ++ "\n" ++ printTree treeB                                                                                                                        
  Empty -> "Empty" 

Output

*Main> main                                                                                                                                                                                                     
4                                                                                                                                                                                                               
3                                                                                                                                                                                                               
Empty                                                                                                                                                                                                           
2                                                                                                                                                                                                               
Empty                                                                                                                                                                                                           
Empty                                                                                                                                                                                                           
Empty 

Desired Output (delimited by tabs or double space is fine)

*Main> main                                                                                                                                                                                                     
    4                                                                                                                                                                                                               
      3                                                                                                                                                                                                               
        Empty                                                                                                                                                                                                           
        2                                                                                                                                                                                                               
          Empty                                                                                                                                                                                                           
          Empty                                                                                                                                                                                                           
      Empty 

Solution

  • You can use an accumulator (here, depth) to keep track of how deep you currently are in the tree - then create a number of spaces corresponding to the depth the line is at:

    main = putStrLn $ printTree tree
    data Tree = Empty | Node Int (Tree) (Tree) deriving (Show)
    tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty
    
    printTree :: Tree -> String
    printTree x = printTree' x 0 
      where 
        printTree' x depth = case x of
          Node num treeA treeB -> (replicate (2 * depth) ' ') ++ show num ++ "\n" ++ (printTree' treeA (depth + 1)) ++ "\n" ++ (printTree' treeB (depth + 1))
          Empty -> (replicate (2 * depth) ' ') ++ "Empty" 
    

    Output:

    *Main> main
    4
      3
        Empty
        2
          Empty
          Empty
      Empty