-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | The Wadler/Leijen Pretty Printer -- @package wl-pprint @version 1.2 -- | Pretty print module based on Philip Wadler's "prettier printer" -- --
-- "A prettier printer" -- Draft paper, April 1997, revised March 1998. -- http://cm.bell-labs.com/cm/cs/who/wadler/papers/prettier/prettier.ps ---- -- PPrint is an implementation of the pretty printing combinators -- described by Philip Wadler (1997). In their bare essence, the -- combinators of Wadler are not expressive enough to describe some -- commonly occurring layouts. The PPrint library adds new primitives to -- describe these layouts and works well in practice. -- -- The library is based on a single way to concatenate documents, which -- is associative and has both a left and right unit. This simple design -- leads to an efficient and short implementation. The simplicity is -- reflected in the predictable behaviour of the combinators which make -- them easy to use in practice. -- -- A thorough description of the primitive combinators and their -- implementation can be found in Philip Wadler's paper (1997). Additions -- and the main differences with his original paper are: -- --
-- show (text "hello" <$> text "world") ---- -- Which would return the string "hello\nworld", i.e. -- --
-- hello -- world --data Doc -- | The action (putDoc doc) pretty prints document doc -- to the standard output, with a page width of 100 characters and a -- ribbon width of 40 characters. -- --
-- main :: IO ()
-- main = do{ putDoc (text "hello" <+> text "world") }
--
--
-- Which would output
--
-- -- hello world --putDoc :: Doc -> IO () -- | (hPutDoc handle doc) pretty prints document doc to -- the file handle handle with a page width of 100 characters -- and a ribbon width of 40 characters. -- --
-- main = do{ handle <- openFile "MyFile" WriteMode
-- ; hPutDoc handle (vcat (map text
-- ["vertical","text"]))
-- ; hClose handle
-- }
--
hPutDoc :: Handle -> Doc -> IO ()
-- | The empty document is, indeed, empty. Although empty has no
-- content, it does have a 'height' of 1 and behaves exactly like
-- (text "") (and is therefore not a unit of
-- <$>).
empty :: 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.
char :: Char -> 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.
text :: String -> Doc
-- | The document (x <> y) concatenates document x
-- and document y. It is an associative operation having
-- empty as a left and right unit. (infixr 6)
(<>) :: Doc -> Doc -> Doc
-- | The document (nest i x) renders document x 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 -- ! --nest :: Int -> Doc -> 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. line :: 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. linebreak :: 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. group :: Doc -> Doc -- | The document softline behaves like space if the -- resulting output fits the page, otherwise it behaves like line. -- --
-- softline = group line --softline :: Doc -- | The document softbreak behaves like empty if the -- resulting output fits the page, otherwise it behaves like line. -- --
-- softbreak = group linebreak --softbreak :: Doc -- | The document (align x) renders document x 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 --align :: Doc -> Doc -- | The hang combinator implements hanging indentation. The document -- (hang i x) renders document x 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) --hang :: Int -> Doc -> Doc -- | The document (indent i x) indents document x with -- i spaces. -- --
-- test = indent 4 (fillSep (map text -- (words "the indent combinator indents these words !"))) ---- -- Which lays out with a page width of 20 as: -- --
-- the indent -- combinator -- indents these -- words ! --indent :: Int -> Doc -> Doc -- | The document (encloseSep l r sep xs) concatenates the -- documents xs separated 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 separators 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] --encloseSep :: Doc -> Doc -> Doc -> [Doc] -> Doc -- | The document (list xs) comma separates 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 separators are put in front of the -- elements. list :: [Doc] -> Doc -- | The document (tupled xs) comma separates 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 separators are put in front of the -- elements. tupled :: [Doc] -> Doc -- | The document (semiBraces xs) separates 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. semiBraces :: [Doc] -> Doc -- | The document (x <+> y) concatenates document x -- and y with a space in between. (infixr 6) (<+>) :: Doc -> Doc -> Doc -- | The document (x <$> y) concatenates document x -- and y with a line in between. (infixr 5) (<$>) :: 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. (infixr 5) (>) :: Doc -> Doc -> Doc -- | The document (x <$$> y) concatenates document -- x and y with a linebreak in between. -- (infixr 5) (<$$>) :: 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. (infixr 5) (/>) :: Doc -> Doc -> Doc -- | The document (hsep xs) concatenates all documents xs -- horizontally with (<+>). hsep :: [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 separated -- 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 --vsep :: [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 --fillSep :: [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) --sep :: [Doc] -> Doc -- | The document (hcat xs) concatenates all documents xs -- horizontally with (<>). hcat :: [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. vcat :: [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 --fillCat :: [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) --cat :: [Doc] -> Doc -- | (punctuate p xs) concatenates all documents in 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.) punctuate :: Doc -> [Doc] -> [Doc] -- | The document (fill i x) renders document x. It than -- appends spaces until the width is equal to i. If the -- width of x is already larger, nothing is appended. This -- combinator is quite useful in practice to output a list of bindings. -- The following example demonstrates this. -- --
-- types = [("empty","Doc")
-- ,("nest","Int -> Doc -> Doc")
-- ,("linebreak","Doc")]
--
-- ptype (name,tp)
-- = fill 6 (text name) <+> text "::" <+> text tp
--
-- test = text "let" <+> align (vcat (map ptype types))
--
--
-- Which is layed out as:
--
-- -- let empty :: Doc -- nest :: Int -> Doc -> Doc -- linebreak :: Doc --fill :: Int -> Doc -> Doc -- | The document (fillBreak i x) first renders document -- x. It than appends spaces until the width is equal -- to i. If the width of x is already larger than -- i, the nesting level is increased by i and a -- line is appended. When we redefine ptype in the -- previous example to use fillBreak, we get a useful variation -- of the previous output: -- --
-- ptype (name,tp) -- = fillBreak 6 (text name) <+> text "::" <+> text tp ---- -- The output will now be: -- --
-- let empty :: Doc -- nest :: Int -> Doc -> Doc -- linebreak -- :: Doc --fillBreak :: Int -> Doc -> Doc -- | The document (enclose l r x) encloses document x -- between documents l and r using (<>). -- --
-- enclose l r x = l <> x <> r --enclose :: Doc -> Doc -> Doc -> Doc -- | Document (squotes x) encloses document x with single -- quotes "'". squotes :: Doc -> Doc -- | Document (dquotes x) encloses document x with double -- quotes '"'. dquotes :: Doc -> Doc -- | Document (parens x) encloses document x in -- parenthesis, "(" and ")". parens :: Doc -> Doc -- | Document (angles x) encloses document x in angles, -- "<" and ">". angles :: Doc -> Doc -- | Document (braces x) encloses document x in braces, -- "{" and "}". braces :: Doc -> Doc -- | Document (brackets x) encloses document x in square -- brackets, "[" and "]". brackets :: Doc -> Doc -- | The document lparen contains a left parenthesis, "(". lparen :: Doc -- | The document rparen contains a right parenthesis, ")". rparen :: Doc -- | The document langle contains a left angle, "<". langle :: Doc -- | The document rangle contains a right angle, ">". rangle :: Doc -- | The document lbrace contains a left brace, "{". lbrace :: Doc -- | The document rbrace contains a right brace, "}". rbrace :: Doc -- | The document lbracket contains a left square bracket, "[". lbracket :: Doc -- | The document rbracket contains a right square bracket, "]". rbracket :: Doc -- | The document squote contains a single quote, "'". squote :: Doc -- | The document dquote contains a double quote, '"'. dquote :: Doc -- | The document semi contains a semi colon, ";". semi :: Doc -- | The document colon contains a colon, ":". colon :: Doc -- | The document comma contains a comma, ",". comma :: Doc -- | The document space contains a single space, " ". -- --
-- x <+> y = x <> space <> y --space :: Doc -- | The document dot contains a single dot, ".". dot :: Doc -- | The document backslash contains a back slash, "\". backslash :: Doc -- | The document equals contains an equal sign, "=". equals :: 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. string :: String -> Doc -- | The document (int i) shows the literal integer i -- using text. int :: Int -> Doc -- | The document (integer i) shows the literal integer i -- using text. integer :: Integer -> Doc -- | The document (float f) shows the literal float f -- using text. float :: Float -> Doc -- | The document (double d) shows the literal double d -- using text. double :: Double -> Doc -- | The document (rational r) shows the literal rational -- r using text. rational :: Rational -> Doc -- | The member prettyList is only used to define the instance -- Pretty a => Pretty [a]. In normal circumstances only the -- pretty function is used. class Pretty a where prettyList = list . map pretty pretty :: Pretty a => a -> Doc prettyList :: Pretty a => [a] -> Doc -- | The data type SimpleDoc represents rendered documents and is -- used by the display functions. -- -- The Int in SText contains the length of the string. -- The Int in SLine contains the indentation for that -- line. The library provides two default display functions -- displayS and displayIO. You can provide your own display -- function by writing a function from a SimpleDoc to your own -- output format. data SimpleDoc SEmpty :: SimpleDoc SChar :: Char -> SimpleDoc -> SimpleDoc SText :: !Int -> String -> SimpleDoc -> SimpleDoc SLine :: !Int -> SimpleDoc -> SimpleDoc -- | This is the default pretty printer which is used by show, -- putDoc and hPutDoc. (renderPretty ribbonfrac width -- x) renders document x with a page width of -- width and a ribbon width of (ribbonfrac * width) -- characters. The ribbon width is the maximal amount of non-indentation -- characters on a line. The parameter ribbonfrac should be -- between 0.0 and 1.0. If it is lower or higher, the -- ribbon width will be 0 or width respectively. renderPretty :: Float -> Int -> Doc -> SimpleDoc -- | (renderCompact x) renders document x without adding -- any indentation. Since no 'pretty' printing is involved, this renderer -- is very fast. The resulting output contains fewer characters than a -- pretty printed version and can be used for output that is read by -- other programs. renderCompact :: Doc -> SimpleDoc -- | (displayS simpleDoc) takes the output simpleDoc from -- a rendering function and transforms it to a ShowS type (for use -- in the Show class). -- --
-- showWidth :: Int -> Doc -> String -- showWidth w x = displayS (renderPretty 0.4 w x) "" --displayS :: SimpleDoc -> ShowS -- | (displayIO handle simpleDoc) writes simpleDoc to the -- file handle handle. This function is used for example by -- hPutDoc: -- --
-- hPutDoc handle doc = displayIO handle (renderPretty 0.4 100 doc) --displayIO :: Handle -> SimpleDoc -> IO () bool :: Bool -> Doc column :: (Int -> Doc) -> Doc nesting :: (Int -> Doc) -> Doc width :: Doc -> (Int -> Doc) -> Doc instance [overlap ok] Show Doc instance [overlap ok] Pretty a => Pretty (Maybe a) instance [overlap ok] (Pretty a, Pretty b, Pretty c) => Pretty (a, b, c) instance [overlap ok] (Pretty a, Pretty b) => Pretty (a, b) instance [overlap ok] Pretty Double instance [overlap ok] Pretty Float instance [overlap ok] Pretty Integer instance [overlap ok] Pretty Int instance [overlap ok] Pretty Char instance [overlap ok] Pretty Bool instance [overlap ok] Pretty () instance [overlap ok] Pretty Doc instance [overlap ok] Pretty a => Pretty [a]