PP structure
June 22, 2026 ยท View on GitHub
The PP structure is a combinator library for pretty-printing, in the
style of Wadler and Leijen. A value of type doc is an abstract document
that describes a piece of text together with the points at which it may
be broken across lines. The render function lays a doc out into a
string, choosing the most compact layout that fits a given line width.
Documents are built from text, the line-break primitives (line,
lineBreak, softLine, softBreak, hardLine), and combinators such as
beside, nest, group, and the list operators sep, cat, fillSep,
and fillCat. A group lays its contents out on a single line if they
fit, and otherwise breaks them.
The combinators follow Philip Wadler's
A prettier printer,
extended with the alignment and fill operators of Daan Leijen's
wl-pprint library. The
renderer follows Christian Lindig's
Strictly Pretty,
an eager implementation that suits a strict language such as Standard ML:
it decides each group in a single forward pass, rather than relying on
the laziness of Wadler's original Haskell version.
Synopsis
type doc val empty : doc val line : doc val lineBreak : doc val softLine : doc val softBreak : doc val hardLine : doc val text : string -> doc val beside : doc * doc -> doc val nest : int * doc -> doc val group : doc -> doc val align : doc -> doc val hang : int * doc -> doc val indent : int * doc -> doc val hsep : doc list -> doc val vsep : doc list -> doc val sep : doc list -> doc val hcat : doc list -> doc val vcat : doc list -> doc val cat : doc list -> doc val fillSep : doc list -> doc val fillCat : doc list -> doc val punctuate : doc * doc list -> doc list val encloseSep : doc * doc * doc * doc list -> doc val parens : doc -> doc val braces : doc -> doc val brackets : doc -> doc val render : int * doc -> string
type doc
is the type of a pretty-printer document.
empty
empty is the empty document.
line
line is a line break. It is rendered as a single space when the enclosing
group fits on one line, and as a newline otherwise.
lineBreak
lineBreak is a line break. It is rendered as nothing when the enclosing group fits
on one line, and as a newline otherwise.
softLine
softLine is a line break that is rendered as a single space when flattened.
softBreak
softBreak is a line break that is rendered as nothing when flattened.
hardLine
hardLine is a line break that is always rendered as a newline, even inside a
group that would otherwise fit on one line.
text
text s is a document containing the literal string s.
beside
beside (a, b) is a placed directly to the left of b, with nothing between them.
nest
nest (i, d) increases the indentation of d by i columns.
group
group d lays d out on one line if it fits, otherwise lays it out broken across
lines.
align
align d sets the indentation of d to the current column.
hang
hang (i, d) renders d with its nesting set to the current column plus i,
placing the first line at the current column.
indent
indent (i, d) indents d by i columns, including its first line.
hsep
hsep ds concatenates the documents ds, separating them with spaces.
vsep
vsep ds concatenates the documents ds, separating them with line breaks.
sep
sep ds concatenates the documents ds, separating them with spaces if the
result fits on one line, and with line breaks otherwise.
hcat
hcat ds concatenates the documents ds with nothing between them.
vcat
vcat ds concatenates the documents ds, separating them with line breaks.
cat
cat ds concatenates the documents ds with nothing between them if the result
fits on one line, and with line breaks otherwise.
fillSep
fillSep ds concatenates the documents ds, separating them with spaces, and
inserting a line break whenever the next document does not fit.
fillCat
fillCat ds concatenates the documents ds with nothing between them, inserting a
line break whenever the next document does not fit.
punctuate
punctuate (sep, ds) inserts the separator sep between each of the documents ds,
returning the resulting list of documents.
encloseSep
encloseSep (open_, close, sep, ds) concatenates the documents ds, separating them with sep and
enclosing the result between open_ and close.
parens
parens d encloses d between parentheses.
braces
braces d encloses d between braces.
brackets
brackets d encloses d between square brackets.
render
render (w, d) renders d to a string, choosing the best layout for line width w.