tpdb-1.5.2: Data Type for Rewriting Systems

Safe HaskellSafe
LanguageHaskell98

TPDB.Pretty

Contents

Synopsis

Documentation

data Doc ann :: * -> * #

The abstract data type Doc ann represents pretty documents that have been annotated with data of type ann.

More specifically, a value of type Doc represents a non-empty set of possible layouts of a document. The layout functions select one of these possibilities, taking into account things like the width of the output document.

The annotation is an arbitrary piece of data associated with (part of) a document. Annotations may be used by the rendering backends in order to display output differently, such as

  • color information (e.g. when rendering to the terminal)
  • mouseover text (e.g. when rendering to rich HTML)
  • whether to show something or not (to allow simple or detailed versions)

The simplest way to display a Doc is via the Show class.

>>> putStrLn (show (vsep ["hello", "world"]))
hello
world

Instances

Functor Doc

Alter the document’s annotations.

This instance makes Doc more flexible (because it can be used in Functor-polymorphic values), but fmap is much less readable compared to using reAnnotate in code that only works for Doc anyway. Consider using the latter when the type does not matter.

Methods

fmap :: (a -> b) -> Doc a -> Doc b #

(<$) :: a -> Doc b -> Doc a #

Show (Doc ann)

(show doc) prettyprints document doc with defaultLayoutOptions, ignoring all annotations.

Methods

showsPrec :: Int -> Doc ann -> ShowS #

show :: Doc ann -> String #

showList :: [Doc ann] -> ShowS #

IsString (Doc ann)
>>> pretty ("hello\nworld")
hello
world

This instance uses the Pretty Text instance, and uses the same newline to line conversion.

Methods

fromString :: String -> Doc ann #

Generic (Doc ann) 

Associated Types

type Rep (Doc ann) :: * -> * #

Methods

from :: Doc ann -> Rep (Doc ann) x #

to :: Rep (Doc ann) x -> Doc ann #

Semigroup (Doc ann)
x <> y = hcat [x, y]
>>> "hello" <> "world" :: Doc ann
helloworld

Methods

(<>) :: Doc ann -> Doc ann -> Doc ann #

sconcat :: NonEmpty (Doc ann) -> Doc ann #

stimes :: Integral b => b -> Doc ann -> Doc ann #

Monoid (Doc ann)
mempty = emptyDoc
mconcat = hcat
>>> mappend "hello" "world" :: Doc ann
helloworld

Methods

mempty :: Doc ann #

mappend :: Doc ann -> Doc ann -> Doc ann #

mconcat :: [Doc ann] -> Doc ann #

type Rep (Doc ann) 
type Rep (Doc ann) = D1 * (MetaData "Doc" "Data.Text.Prettyprint.Doc.Internal" "prettyprinter-1.2.0.1-7ZuCLms8xajGeu88e33QHe" False) ((:+:) * ((:+:) * ((:+:) * (C1 * (MetaCons "Fail" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "Empty" PrefixI False) (U1 *)) (C1 * (MetaCons "Char" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 * Char))))) ((:+:) * (C1 * (MetaCons "Text" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 * Int)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 * Text)))) ((:+:) * (C1 * (MetaCons "Line" PrefixI False) (U1 *)) (C1 * (MetaCons "FlatAlt" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann))) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann)))))))) ((:+:) * ((:+:) * (C1 * (MetaCons "Cat" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann))) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann))))) ((:+:) * (C1 * (MetaCons "Nest" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 * Int)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann))))) (C1 * (MetaCons "Union" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann))) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann))))))) ((:+:) * ((:+:) * (C1 * (MetaCons "Column" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Int -> Doc ann)))) (C1 * (MetaCons "WithPageWidth" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (PageWidth -> Doc ann))))) ((:+:) * (C1 * (MetaCons "Nesting" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Int -> Doc ann)))) (C1 * (MetaCons "Annotated" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * ann)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Doc ann)))))))))

class Pretty a where #

Overloaded conversion to Doc.

Laws:

  1. output should be pretty. :-)

Minimal complete definition

pretty

Methods

pretty :: a -> Doc ann #

>>> pretty 1 <+> pretty "hello" <+> pretty 1.234
1 hello 1.234

prettyList :: [a] -> Doc ann #

prettyList is only used to define the instance Pretty a => Pretty [a]. In normal circumstances only the pretty function is used.

>>> prettyList [1, 23, 456]
[1, 23, 456]

Instances

Pretty Bool
>>> pretty True
True

Methods

pretty :: Bool -> Doc ann #

prettyList :: [Bool] -> Doc ann #

Pretty Char

Instead of (pretty '\n'), consider using line as a more readable alternative.

>>> pretty 'f' <> pretty 'o' <> pretty 'o'
foo
>>> pretty ("string" :: String)
string

Methods

pretty :: Char -> Doc ann #

prettyList :: [Char] -> Doc ann #

Pretty Double
>>> pretty (exp 1 :: Double)
2.718281828459045

Methods

pretty :: Double -> Doc ann #

prettyList :: [Double] -> Doc ann #

Pretty Float
>>> pretty (pi :: Float)
3.1415927

Methods

pretty :: Float -> Doc ann #

prettyList :: [Float] -> Doc ann #

Pretty Int
>>> pretty (123 :: Int)
123

Methods

pretty :: Int -> Doc ann #

prettyList :: [Int] -> Doc ann #

Pretty Int8 

Methods

pretty :: Int8 -> Doc ann #

prettyList :: [Int8] -> Doc ann #

Pretty Int16 

Methods

pretty :: Int16 -> Doc ann #

prettyList :: [Int16] -> Doc ann #

Pretty Int32 

Methods

pretty :: Int32 -> Doc ann #

prettyList :: [Int32] -> Doc ann #

Pretty Int64 

Methods

pretty :: Int64 -> Doc ann #

prettyList :: [Int64] -> Doc ann #

Pretty Integer
>>> pretty (2^123 :: Integer)
10633823966279326983230456482242756608

Methods

pretty :: Integer -> Doc ann #

prettyList :: [Integer] -> Doc ann #

Pretty Natural 

Methods

pretty :: Natural -> Doc ann #

prettyList :: [Natural] -> Doc ann #

Pretty Word 

Methods

pretty :: Word -> Doc ann #

prettyList :: [Word] -> Doc ann #

Pretty Word8 

Methods

pretty :: Word8 -> Doc ann #

prettyList :: [Word8] -> Doc ann #

Pretty Word16 

Methods

pretty :: Word16 -> Doc ann #

prettyList :: [Word16] -> Doc ann #

Pretty Word32 

Methods

pretty :: Word32 -> Doc ann #

prettyList :: [Word32] -> Doc ann #

Pretty Word64 

Methods

pretty :: Word64 -> Doc ann #

prettyList :: [Word64] -> Doc ann #

Pretty ()
>>> pretty ()
()

The argument is not used,

>>> pretty (error "Strict?" :: ())
()

Methods

pretty :: () -> Doc ann #

prettyList :: [()] -> Doc ann #

Pretty Text

Automatically converts all newlines to line.

>>> pretty ("hello\nworld" :: Text)
hello
world

Note that line can be undone by group:

>>> group (pretty ("hello\nworld" :: Text))
hello world

Manually use hardline if you definitely want newlines.

Methods

pretty :: Text -> Doc ann #

prettyList :: [Text] -> Doc ann #

Pretty Text

(lazy Text instance, identical to the strict version)

Methods

pretty :: Text -> Doc ann #

prettyList :: [Text] -> Doc ann #

Pretty Void

Finding a good example for printing something that does not exist is hard, so here is an example of printing a list full of nothing.

>>> pretty ([] :: [Void])
[]

Methods

pretty :: Void -> Doc ann #

prettyList :: [Void] -> Doc ann #

Pretty Attributes # 

Methods

pretty :: Attributes -> Doc ann #

prettyList :: [Attributes] -> Doc ann #

Pretty CertificationProblemInput # 
Pretty a => Pretty [a]
>>> pretty [1,2,3]
[1, 2, 3]

Methods

pretty :: [a] -> Doc ann #

prettyList :: [[a]] -> Doc ann #

Pretty a => Pretty (Maybe a)

Ignore Nothings, print Just contents.

>>> pretty (Just True)
True
>>> braces (pretty (Nothing :: Maybe Bool))
{}
>>> pretty [Just 1, Nothing, Just 3, Nothing]
[1, 3]

Methods

pretty :: Maybe a -> Doc ann #

prettyList :: [Maybe a] -> Doc ann #

Pretty a => Pretty (NonEmpty a) 

Methods

pretty :: NonEmpty a -> Doc ann #

prettyList :: [NonEmpty a] -> Doc ann #

Pretty a => Pretty (Marked a) # 

Methods

pretty :: Marked a -> Doc ann #

prettyList :: [Marked a] -> Doc ann #

(Pretty a1, Pretty a2) => Pretty (a1, a2)
>>> pretty (123, "hello")
(123, hello)

Methods

pretty :: (a1, a2) -> Doc ann #

prettyList :: [(a1, a2)] -> Doc ann #

(Pretty a1, Pretty a2, Pretty a3) => Pretty (a1, a2, a3)
>>> pretty (123, "hello", False)
(123, hello, False)

Methods

pretty :: (a1, a2, a3) -> Doc ann #

prettyList :: [(a1, a2, a3)] -> Doc ann #

render :: Doc ann -> Text Source #

fsep :: [Doc ann] -> Doc ann Source #

sep :: [Doc ann] -> Doc ann Source #

hsep :: [Doc ann] -> Doc ann Source #

vsep :: [Doc ann] -> Doc ann Source #

vcat :: [Doc ann] -> Doc ann Source #

hcat :: [Doc ann] -> Doc ann Source #

parens :: Doc ann -> Doc ann #

>>> parens "·"
(·)

brackets :: Doc ann -> Doc ann #

>>> brackets "·"
[·]

angles :: Doc ann -> Doc ann #

>>> angles "·"
<·>

braces :: Doc ann -> Doc ann #

>>> braces "·"
{·}

enclose #

Arguments

:: Doc ann

L

-> Doc ann

R

-> Doc ann

x

-> Doc ann

LxR

(enclose l r x) encloses document x between documents l and r using <>.

>>> enclose "A" "Z" "·"
A·Z
enclose l r x = l <> x <> r

encloseSep #

Arguments

:: Doc ann

left delimiter

-> Doc ann

right delimiter

-> Doc ann

separator

-> [Doc ann]

input documents

-> Doc ann 

(encloseSep l r sep xs) concatenates the documents xs separated by sep, and encloses the resulting document by l and r.

The documents are laid out horizontally if that fits the page,

>>> let doc = "list" <+> align (encloseSep lbracket rbracket comma (map pretty [1,20,300,4000]))
>>> putDocW 80 doc
list [1,20,300,4000]

If there is not enough space, then the input is split into lines entry-wise therwise they are laid out vertically, with separators put in the front:

>>> putDocW 10 doc
list [1
     ,20
     ,300
     ,4000]

Note that doc contains an explicit call to align so that the list items are aligned vertically.

For putting separators at the end of entries instead, have a look at punctuate.

punctuate #

Arguments

:: Doc ann

Punctuation, e.g. comma

-> [Doc ann] 
-> [Doc ann] 

(punctuate p xs) appends p to all but the last document in xs.

>>> let docs = punctuate comma (Util.words "lorem ipsum dolor sit amet")
>>> putDocW 80 (hsep docs)
lorem, ipsum, dolor, sit, amet

The separators are put at the end of the entries, which we can see if we position the result vertically:

>>> putDocW 20 (vsep docs)
lorem,
ipsum,
dolor,
sit,
amet

If you want put the commas in front of their elements instead of at the end, you should use tupled or, in general, encloseSep.

comma :: Doc ann #

>>> comma
,

nest #

Arguments

:: Int

Change of nesting level

-> Doc ann 
-> Doc ann 

(nest i x) lays out the document x with the current indentation level increased by i. Negative values are allowed, and decrease the nesting level accordingly.

>>> vsep [nest 4 (vsep ["lorem", "ipsum", "dolor"]), "sit", "amet"]
lorem
    ipsum
    dolor
sit
amet

See also hang, align and indent.

list :: [Doc ann] -> Doc ann #

Haskell-inspired variant of encloseSep with braces and comma as separator.

>>> let doc = list (map pretty [1,20,300,4000])
>>> putDocW 80 doc
[1, 20, 300, 4000]
>>> putDocW 10 doc
[ 1
, 20
, 300
, 4000 ]

tupled :: [Doc ann] -> Doc ann #

Haskell-inspired variant of encloseSep with parentheses and comma as separator.

>>> let doc = tupled (map pretty [1,20,300,4000])
>>> putDocW 80 doc
(1, 20, 300, 4000)
>>> putDocW 10 doc
( 1
, 20
, 300
, 4000 )

empty :: Doc ann Source #

text :: String -> Doc ann Source #

(<+>) :: Doc ann -> Doc ann -> Doc ann Source #

($$) :: Doc ann -> Doc ann -> Doc ann Source #

indent #

Arguments

:: Int

Number of spaces to increase indentation by

-> Doc ann 
-> Doc ann 

(indent i x) indents document x with i spaces, starting from the current cursor position.

>>> let doc = reflow "The indent function indents these words!"
>>> putDocW 24 ("prefix" <> indent 4 doc)
prefix    The indent
          function
          indents these
          words!
indent i d = hang i ({i spaces} <> d)

nest #

Arguments

:: Int

Change of nesting level

-> Doc ann 
-> Doc ann 

(nest i x) lays out the document x with the current indentation level increased by i. Negative values are allowed, and decrease the nesting level accordingly.

>>> vsep [nest 4 (vsep ["lorem", "ipsum", "dolor"]), "sit", "amet"]
lorem
    ipsum
    dolor
sit
amet

See also hang, align and indent.

hang #

Arguments

:: Int

Change of nesting level, relative to the start of the first line

-> Doc ann 
-> Doc ann 

(hang i x) lays out the document x with a nesting level set to the current column plus i. Negative values are allowed, and decrease the nesting level accordingly.

>>> let doc = reflow "Indenting these words with hang"
>>> putDocW 24 ("prefix" <+> hang 4 doc)
prefix Indenting these
           words with
           hang

This differs from nest, which is based on the current nesting level plus i. When you're not sure, try the more efficient nest first. In our example, this would yield

>>> let doc = reflow "Indenting these words with nest"
>>> putDocW 24 ("prefix" <+> nest 4 doc)
prefix Indenting these
    words with nest
hang i doc = align (nest i doc)

Orphan instances

(Pretty a, Pretty b) => Pretty (Either a b) Source #

WARNING: there is instance Pretty a => Pretty (Maybe a) in the back-end but its spec is "Ignore Nothings, print Just contents"

Methods

pretty :: Either a b -> Doc ann #

prettyList :: [Either a b] -> Doc ann #

(Pretty a, Pretty b, Pretty c, Pretty d) => Pretty (a, b, c, d) Source # 

Methods

pretty :: (a, b, c, d) -> Doc ann #

prettyList :: [(a, b, c, d)] -> Doc ann #