A pretty printer library in Haskell
Version 3.0, 28 May 1997
Version 3.0 adds new exports and fixes a bad performance bug. See comments
at the start of the source code.
I have now bitten the bullet and made an "industrial strength" (I hope)
pretty printing library in Haskell, based on John Hughes's paper
"The Design of a Pretty-printing Library" (in Advanced Functional Programming,
Johan Jeuring and Erik Meijer (eds), LNCS 925).
In this zip file are:
-
Pretty.lhs: a version for GHC (0.29 and earlier).
The GHC version uses unboxed types to get a little more speed. You
need to compile with -glasgow-exts -cpp.
-
Pretty.hs: A version for Hugs.
This code has been processed by cpp, so it has tons of white space in it. But it works.
Look in the GHC verision for nicer layout.
-
Main.hs, MainHugs.hs: A test program for GHC and Hugs respectively.
Among other things this code shows how you can use the library to print
lists like this:
[ foo, baz,
, this, that,
, the other
]
which is hard using the original combinators.
Please do try it out, and give me feedback about
- what combinators it lacks
- performance (time and space)
- naming of the combinators
Relative to John's original paper, there are the following new features:
-
There's an empty document, "empty". It's a left and right unit for
both <> and $$, and anywhere in the argument list for
sep, hcat, hsep, vcat, fcat etc.
It is Really Useful in practice.
(John identified the lack of an empty document as a shortcoming in his paper, but
couldn't see how to fit it into the algebra.)
- There is a paragraph-fill combinator, fsep, that's much like sep,
only it keeps fitting things on one line until itc can't fit any more.
- Some random useful extra combinators are provided.
- <+> puts its arguments beside each other with a space between them,
unless either argument is empty in which case it returns the other
- hcat is a list version of <>
- hsep is a list version of <+>
- vcat is a list version of $$
- cat is behaves like sep, but it uses <#> for horizontal conposition
- fcat is behaves like fsep, but it uses <#> for horizontal conposition
- These new ones do the obvious things:
char, semi, comma, colon, space,
parens, brackets, braces,
quotes, doubleQuotes
- The "above" combinator, $$, now overlaps its two arguments if the
last line of the top argument stops before the first line of the second begins.
For example: text "hi" $$ nest 5 "there"
lays out as
hi there
rather than
hi
there
The combinator $+$ gives the original "never-overlap" behaviour.
- Several different renderers are provided:
- a standard one
- one that uses cut-marks to avoid deeply-nested documents
simply piling up in the right-hand margin
- one that ignores indentation (fewer chars output; good for machines)
- one that ignores indentation and newlines (ditto, only more so)
- Numerous implementation tidy-ups, plus (for GHC)
the use of unboxed data types to speed up the implementation