A pretty printer library in Haskell
Version 3.0 adds new exports and fixes a bad performance bug. See comments
at the start of the source code.
Version 3.0, 28 May 1997
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
Relative to John's original paper, there are the following new features:
- what combinators it lacks
- performance (time and space)
- naming of the combinators
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,
- 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
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