Evan Martin (evan) wrote in evan_tech,
Evan Martin

haskell trick #3: use the pretty-printer

Here's an underappreciated Haskell standard library.

Text.PrettyPrint provides combinators for pretty-printing. It's kinda like a super-simplified HTML or TeX: you give it a bunch of boxes and how they relate to one another and it manages output. It's trivial to use.

A common case I have is printing something that's tree-like, where children are indented below their parents. The code for printing a node is straightforward: print this node's content, then map the print function over all its children with a bit more indentation. But the indentation bit is annoying! You have to remember to properly indent every line, and then that complicated wrapping, etc.

Instead, use the pretty-printer. A Doc is basically a box of text. text "foo" produces a Doc with that string. Then there are higher-level functions to compose Docs: nest indents a Doc, vcat puts a sequence of docs together, one above the other... and finally render converts a Doc to a string.

For my expenses chart I pretty-printed the parsed version of my expenses data.

showDays :: [DayLog] -> String
showDays days = render (vcat (map showDay days)) where
  showDay (DayLog day exps) = text (show day) <+> vcat (map showExp exps)
  showExp (Expense cost desc tags) = text (show cost) <+> text desc
                                 <+> showTags tags
  showTags tags = text "[" <> hsep (map text tags) <> text "]"

showDays outputs a sequence of days by vcatting them together.
showDay shows a single day by writing out the date on the left and then all the day's expenses vertically listed the right.
showExp and showTags just write out the fields in sequence, more or less.

The output looks like this:
2003-03-15 16 airport food [food]
2003-03-23 10 bart [transport]
           9 burger [food]
           10 ikea teapot [home]
           1 ikea water [drink]
All the expenses properly indented over on the right. (I didn't track expenses on my vacation, so there's a gap in the dates there...)
Tags: haskell, howto

  • your vcs sucks

    I've been hacking on some Haskell stuff lately that's all managed in darcs and it's reminded me of an observation I made over two years ago now (see…

  • git evangelism: enough already

    As a person who uses Git extensively and thoroughly, and as someone works on/around two large open source projects (Chrome, WebKit) that are managed…

  • using git with svnsync

    git.chromium.org is a git-svn mirror of the canonical SVN repository. It works like this: the SVN server pushes out, with svnsync, a mirror to…

  • Post a new comment


    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.