The interface is that of
Daan Leijen's library
(fill, fillBreak and indent
are missing) with a
linear-time, bounded implementation by Olaf Chitil.
Author: Sebastian Fischer
Version: October 2006
| Exported names: |
Datatypes:
Doc
Functions:
<$$>
| <$>
| <+>
| <//>
| </>
| <>
| align
| angles
| backslash
| bquotes
| braces
| brackets
| cat
| char
| colon
| combine
| comma
| compose
| dot
| dquote
| dquotes
| empty
| enclose
| encloseSep
| equals
| fillCat
| fillEncloseSep
| fillSep
| float
| group
| hang
| hcat
| hEncloseSep
| hsep
| int
| langle
| lbrace
| lbracket
| line
| linebreak
| linesep
| list
| lparen
| nest
| parens
| pretty
| punctuate
| rangle
| rbrace
| rbracket
| rparen
| semi
| semiBraces
| sep
| softbreak
| softline
| space
| squote
| squotes
| string
| text
| tupled
| vcat
| vsep
| Summary of exported functions: |
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
| Imported modules: |
| Exported datatypes: |
The abstract data type Doc represents pretty documents.
Constructors:
| Exported functions: |
:: Doc
The empty document is, indeed, empty. Allthough empty has no content,
it does have a 'height' of 1 and behaves exactly like (text "")
(and is therefore not a unit of <$>).
:: String -> Doc
The document (text s) contains the literal string s.
The string shouldn't contain any newline ('\n') characters.
If the string contains newline characters,
the function string should be used.
Example call: (text s)
s
- a string without newline ('\n') characters
:: String -> Doc
The document (linesep s) advances to the next line and indents to the current nesting level. Document (linesep s) behaves like (text s) if the line break is undone by group.
Example call: (linesep s)
s
- a string
:: Doc
The line document advances to the next line and indents to the current nesting level. Document line behaves like (text " ") if the line break is undone by group.
:: Doc
The linebreak document advances to the next line and indents to the current nesting level. Document linebreak behaves like empty if the line break is undone by group.
:: Doc
The document softline behaves like space if the resulting output
fits the page, otherwise it behaves like line.
softline = group line
space or line
:: Doc
The document softbreak behaves like empty if the resulting output
fits the page, otherwise it behaves like line.
softbreak = group linebreak
empty or line
:: Doc -> Doc
The group combinator is used to specify alternative layouts. The document (group x) undoes all line breaks in document x. The resulting line is added to the current line if that fits the page. Otherwise, the document x is rendered without any changes.
Example call: (group d)
d
- a document
:: Int -> Doc -> Doc
The document (nest i d) renders document d with the current
indentation level increased by i (See also hang,
align and indent).
nest 2 (text "hello" <$> text "world") <$> text "!"
outputs as:
hello
world
!
Example call: (nest i d)
i
- an integer which increases the indentation level
d
- a document
:: Int -> Doc -> Doc
The hang combinator implements hanging indentation.
The document (hang i d) renders document d with a nesting level set
to the current column plus i. The following example uses hanging
indentation for some text:
test = hang 4 (fillSep (map text
(words "the hang combinator indents these words !")))
Which lays out on a page with a width of 20 characters as:
the hang combinator
indents these
words !
The hang combinator is implemented as:
hang i x = align (nest i x)
Example call: (hang i d)
i
- an integer which increases the indentation level
d
- a document
:: Doc -> Doc
The document (align d) renders document d with the nesting level
set to the current column. It is used for example to implement hang.
As an example, we will put a document right above another one,
regardless of the current nesting level:
x $$ y = align (x <$> y)
test = text "hi" <+> (text "nice" $$ text "world")
which will be layed out as:
hi nice
world
Example call: (align d)
d
- a document
:: Doc -> Doc -> Doc -> Doc
The document (combine x l r) encloses document x between
documents l and r using (<>).
combine x l r = l <> x <> r
Example call: (combine x l r)
x
- the middle document
l
- the left document
r
- the right document
:: Doc -> Doc -> Doc
The document (x <> y) concatenates document x and document y. It is an associative operation having empty as a left and right unit.
Example call: (x <> y)
x
- the first document
y
- the second document
:: Doc -> Doc -> Doc
The document (x <+> y) concatenates document x and y with a
space in between.
Example call: (x <+> y)
x
- the first document
y
- the second document
space in between
:: Doc -> Doc -> Doc
The document (x <$> y) concatenates document x and y with a
line in between.
Example call: (x <$> y)
x
- the first document
y
- the second document
line in between
:: Doc -> Doc -> Doc
The document (x </> y) concatenates document x and y with
a softline in between. This effectively puts x and y either
next to each other (with a space in between)
or underneath each other.
Example call: (x </> y)
x
- the first document
y
- the second document
softline in between
:: Doc -> Doc -> Doc
The document (x <$$> y) concatenates document x and y with a
linebreak in between.
Example call: (x <$$> y)
x
- the first document
y
- the second document
linebreak in between
:: Doc -> Doc -> Doc
The document (x <//> y) concatenates document x and y with a
softbreak in between. This effectively puts x and y either
right next to each other or underneath each other.
Example call: (x <//> y)
x
- the first document
y
- the second document
softbreak in between
:: (Doc -> Doc -> Doc) -> [Doc] -> Doc
The document (compose f xs) concatenates all documents xs with function f.
Function f should be like (<+>), (<$>) and so on.
Example call: (compose f xs)
f
- a combiner function
xs
- a list of documents
:: [Doc] -> Doc
The document (hsep xs) concatenates all documents xs
horizontally with (<+>).
Example call: (hsep xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (vsep xs) concatenates all documents xs vertically with
(<$>). If a group undoes the line breaks inserted by vsep,
all documents are seperated with a space.
someText = map text (words ("text to lay out"))
test = text "some" <+> vsep someText
This is layed out as:
some text
to
lay
out
The align combinator can be used to align the documents
under their first element
test = text "some" <+> align (vsep someText)
Which is printed as:
some text
to
lay
out
Example call: (vsep xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (fillSep xs) concatenates documents xs horizontally with
(<+>) as long as its fits the page, than inserts a
line and continues doing that for all documents in xs.
fillSep xs = foldr (</>) empty xs
Example call: (fillSep xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (sep xs) concatenates all documents xs either horizontally
with (<+>), if it fits the page, or vertically
with (<$>).
sep xs = group (vsep xs)
Example call: (sep xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (hcat xs) concatenates all documents xs horizontally
with (<>).
Example call: (hcat xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (vcat xs) concatenates all documents xs vertically
with (<$$>). If a group undoes the line
breaks inserted by vcat, all documents are directly
concatenated.
Example call: (vcat xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (fillCat xs) concatenates documents xs horizontally
with (<>) as long as its fits the page, than inserts
a linebreak and continues doing that for all documents in xs.
fillCat xs = foldr (<//>) empty xs
Example call: (fillCat xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (cat xs) concatenates all documents xs either horizontally
with (<>), if it fits the page, or vertically with
(<$$>).
cat xs = group (vcat xs)
Example call: (cat xs)
xs
- a list of documents
:: Doc -> [Doc] -> [Doc]
(punctuate p xs) concatenates all in documents xs with document p except
for the last document.
someText = map text ["words","in","a","tuple"]
test = parens (align (cat (punctuate comma someText)))
This is layed out on a page width of 20 as:
(words,in,a,tuple)
But when the page width is 15, it is layed out as:
(words,
in,
a,
tuple)
(If you want put the commas in front of their elements instead of at the
end, you should use tupled or, in general,
encloseSep.)
Example call: (punctuate p xs)
p
- a document as seperator
xs
- a list of documents
:: Doc -> Doc -> Doc -> [Doc] -> Doc
The document (encloseSep l r sep xs) concatenates the documents xs
seperated by sep and encloses the resulting document by l and r.
The documents are rendered horizontally if that fits the page. Otherwise
they are aligned vertically. All seperators are put in front of the
elements.
For example, the combinator list can be defined with
encloseSep:
list xs = encloseSep lbracket rbracket comma xs
test = text "list" <+> (list (map int [10,200,3000]))
Which is layed out with a page width of 20 as:
list [10,200,3000]
But when the page width is 15, it is layed out as:
list [10
,200
,3000]
Example call: (encloseSep l r sep xs)
l
- left document
r
- right document
sep
- a document as seperator
xs
- a list of documents
:: Doc -> Doc -> Doc -> [Doc] -> Doc
The document (hEncloseSep l r sep xs) concatenates the documents xs
seperated by sep and encloses the resulting document by l and r.
The documents are rendered horizontally.
Example call: (hEncloseSep l r sep xs)
l
- left document
r
- right document
sep
- a document as seperator
xs
- a list of documents
:: Doc -> Doc -> Doc -> [Doc] -> Doc
The document (hEncloseSep l r sep xs) concatenates the documents xs
seperated by sep and encloses the resulting document by l and r.
The documents are rendered horizontally if that fits the page.
Otherwise they are aligned vertically.
All seperators are put in front of the elements.
Example call: (fillEncloseSep l r sep xs)
l
- left document
r
- right document
sep
- a document as seperator
xs
- a list of documents
:: [Doc] -> Doc
The document (list xs) comma seperates the documents xs and encloses them in square brackets. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All comma seperators are put in front of the elements.
Example call: (list xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (tupled xs) comma seperates the documents xs and encloses them in parenthesis. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All comma seperators are put in front of the elements.
Example call: (tupled xs)
xs
- a list of documents
:: [Doc] -> Doc
The document (semiBraces xs) seperates the documents xs with semi colons and encloses them in braces. The documents are rendered horizontally if that fits the page. Otherwise they are aligned vertically. All semi colons are put in front of the elements.
Example call: (semiBraces xs)
xs
- a list of documents
:: Doc -> Doc -> Doc -> Doc
The document (enclose l r x) encloses document x between
documents l and r using (<>).
enclose l r x = l <> x <> r
Example call: (enclose l r x)
l
- the left document
r
- the right document
x
- the middle document
:: Doc -> Doc
Document (squotes x) encloses document x with single quotes "'".
Example call: (squotes x)
x
- a document
:: Doc -> Doc
Document (dquotes x) encloses document x with double quotes '"'.
Example call: (dquotes x)
x
- a document
:: Doc -> Doc
Document (bquotes x) encloses document x with '`' quotes.
Example call: (bquotes x)
x
- a document
'`' quotes
:: Doc -> Doc
Document (parens x) encloses document x in parenthesis,
"(" and ")".
Example call: (parens x)
x
- a document
:: Doc -> Doc
Document (angles x) encloses document x in angles,
"<" and ">".
Example call: (angles x)
x
- a document
:: Doc -> Doc
Document (braces x) encloses document x in braces,
"{" and "}".
Example call: (braces x)
x
- a document
:: Doc -> Doc
Document (brackets x) encloses document x in square brackets,
"[" and "]".
Example call: (brackets x)
x
- a document
:: Char -> Doc
The document (char c) contains the literal character c.
The character shouldn't be a newline ('\n'),
the function line should be used for line breaks.
Example call: (char c)
c
- a character
:: String -> Doc
The document (string s) concatenates all characters in s using
line for newline characters and char for all
other characters. It is used instead of text whenever the
text contains newline characters.
Example call: (string s)
s
- a string
:: Int -> Doc
The document (int i) shows the literal integer i using text.
Example call: (int i)
i
- an integer
:: Float -> Doc
The document (float f) shows the literal float f using text.
Example call: (float f)
f
- a float
:: Doc
The document lparen contains a left parenthesis, "(".
:: Doc
The document rparen contains a right parenthesis, ")".
:: Doc
The document langle contains a left angle, "<".
:: Doc
The document rangle contains a right angle, ">".
:: Doc
The document lbrace contains a left brace, "{".
:: Doc
The document rbrace contains a right brace, "}".
:: Doc
The document lbracket contains a left square bracket, "[".
:: Doc
The document rbracket contains a right square bracket, "]".
:: Doc
The document squote contains a single quote, "'".
:: Doc
The document dquote contains a double quote, '"'.
:: Doc
The document semi contains a semi colon, ";".
:: Doc
The document colon contains a colon, ":".
:: Doc
The document comma contains a comma, ",".
:: Doc
The document space contains a single space, " ".
x <+> y = x <> space <> y
:: Doc
The document dot contains a single dot, ".".
:: Doc
The document backslash contains a back slash, "\\".
:: Doc
The document equals contains an equal sign, "=".
:: Int -> Doc -> String
(pretty w d) pretty prints document d with a page width of w characters
Example call: (pretty w d)
w
- width of page
d
- a document