packages feed

rio-prettyprint 0.1.5.0 → 0.1.6.0

raw patch · 4 files changed

+430/−114 lines, 4 files

Files

rio-prettyprint.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.35.4.
+-- This file has been generated from package.yaml by hpack version 0.35.5.
 --
 -- see: https://github.com/sol/hpack
 
 name:           rio-prettyprint
-version:        0.1.5.0
+version:        0.1.6.0
 synopsis:       Pretty-printing for RIO
 description:    Combine RIO's log capabilities with pretty printing
 category:       Development
src/RIO/PrettyPrint.hs view
@@ -12,27 +12,43 @@   , displayPlain
   , displayWithColor
     -- * Logging based on pretty-print typeclass
+    -- | The @pretty...@ functions come in three varieties:
+    --
+    -- * The normal variety, with a single styled document;
+    -- * The @L@ variety. The listed styled documents are concatenated with
+    --   'fillSep'; and
+    -- * The @S@ variety. 'flow' is applied to the 'String'.
+    --
+    -- Pretty message at log level 'LevelDebug'.
   , prettyDebug
-  , prettyInfo
-  , prettyNote
-  , prettyWarn
-  , prettyError
-  , prettyWarnNoIndent
-  , prettyErrorNoIndent
   , prettyDebugL
-  , prettyInfoL
-  , prettyNoteL
-  , prettyWarnL
-  , prettyErrorL
-  , prettyWarnNoIndentL
-  , prettyErrorNoIndentL
   , prettyDebugS
+    -- | Pretty message at log level 'LevelInfo'.
+  , prettyInfo
+  , prettyInfoL
   , prettyInfoS
+    -- | Pretty messages at log level 'LevelInfo', starting on a new line with
+    -- label @Note:@, with the message indented after the label.
+  , prettyNote
+  , prettyNoteL
   , prettyNoteS
+    -- | Pretty messages at log level 'LevelWarn', starting on a new line with
+    -- label @Warning:@, with or without the message indented after the label.
+  , prettyWarn
+  , prettyWarnL
   , prettyWarnS
-  , prettyErrorS
+  , prettyWarnNoIndent
+  , prettyWarnNoIndentL
   , prettyWarnNoIndentS
+    -- | Pretty messages at log level 'LevelError', starting on a new line with
+    -- label @Error:@, with or without the message indented after the label.
+  , prettyError
+  , prettyErrorL
+  , prettyErrorS
+  , prettyErrorNoIndent
+  , prettyErrorNoIndentL
   , prettyErrorNoIndentS
+
     -- * Semantic styling functions
     -- | These are used rather than applying colors or other styling directly,
     -- to provide consistency.
@@ -41,8 +57,9 @@   , logLevelToStyle
     -- * Formatting utils
   , bulletedList
-  , mkNarrativeList
   , spacedBulletedList
+  , mkBulletedList
+  , mkNarrativeList
   , debugBracket
     -- * Re-exports from "Text.PrettyPrint.Leijen.Extended"
   , Pretty (..)
@@ -185,7 +202,7 @@ indentAfterLabel :: StyleDoc -> StyleDoc
 indentAfterLabel = align
 
--- | Make a 'Doc' from each word in a 'String'
+-- | Make a 'StyleDoc' from each word in a 'String'
 wordDocs :: String -> [StyleDoc]
 wordDocs = map fromString . words
 
@@ -193,6 +210,22 @@ flow :: String -> StyleDoc
 flow = fillSep . wordDocs
 
+-- | @debug message action@ brackets any output of the specified @action@ with
+-- an initial and final @message@ at log level 'LevelDebug'. The initial message
+-- is prefixed with the label @Start:@. The final message is prefixed with
+-- information about the duration of the action in milliseconds (ms) and, if
+-- an exception is thrown by the action, the exception. For example:
+--
+-- > Start: <message>
+-- > <output of action>
+-- > Finished in ...ms: <message>
+--
+-- or:
+--
+-- > Start: <message>
+-- > <output of action>
+-- > Finished with exception in ...ms: <message>
+-- > Exception thrown: <exception_message>
 debugBracket :: (HasCallStack, HasTerm env, MonadReader env m,
                  MonadIO m, MonadUnliftIO m) => StyleDoc -> m a -> m a
 debugBracket msg f = do
@@ -215,19 +248,38 @@   output $ "Finished in" <+> displayMilliseconds diff <> ":" <+> msg
   return x
 
--- |Annotate a 'StyleDoc' with a 'Style'.
+-- | Annotate a 'StyleDoc' with a 'Style'.
 style :: Style -> StyleDoc -> StyleDoc
 style = styleAnn
 
--- Display milliseconds.
-displayMilliseconds :: Double -> StyleDoc
+-- | Display as milliseconds in style 'Good'.
+displayMilliseconds ::
+     Double
+     -- ^ Amount of time in seconds.
+  -> StyleDoc
 displayMilliseconds t = style Good $
   fromString (show (round (t * 1000) :: Int)) <> "ms"
 
--- | Display a bulleted list of 'StyleDoc'.
+-- | Display a bulleted list of 'StyleDoc' with @*@ as the bullet point.
 bulletedList :: [StyleDoc] -> StyleDoc
-bulletedList = mconcat . intersperse line . map (("*" <+>) . align)
+bulletedList = mkBulletedList False '*'
 
+-- | Display a bulleted list of 'StyleDoc', spaced with blank lines or not,
+-- given a character for the bullet point.
+--
+-- @since 0.1.6.0
+mkBulletedList ::
+     Bool
+     -- ^ Spaced with a blank line between each item?
+  -> Char
+     -- ^ The character to act as the bullet point.
+  -> [StyleDoc] 
+  -> StyleDoc
+mkBulletedList isSpaced bullet = 
+  mconcat . intersperse spacer . map ((fromString [bullet] <+>) . align)
+ where
+  spacer = if isSpaced then line <> line else line
+
 -- | A helper function to yield a narrative list from a list of items, with a
 -- final fullstop. For example, helps produce the output
 -- @\"apple, ball and cat.\"@ (no serial comma) or @\"apple, ball, and cat.\"@
@@ -255,9 +307,9 @@   : mkNarrativeList mStyle useSerialComma xs
 
 -- | Display a bulleted list of 'StyleDoc' with a blank line between
--- each.
+-- each and @*@ as the bullet point.
 spacedBulletedList :: [StyleDoc] -> StyleDoc
-spacedBulletedList = mconcat . intersperse (line <> line) . map (("*" <+>) . align)
+spacedBulletedList = mkBulletedList True '*'
 
 -- | The 'Style' intended to be associated with a 'LogLevel'.
 --
src/RIO/PrettyPrint/Types.hs view
@@ -17,44 +17,56 @@ import           RIO
 import           System.Console.ANSI.Types ( SGR )
 
--- | A style of rio-prettyprint's output.
+-- | Type representing styles of output.
 data Style
-  = Error     -- Should be used sparingly, not to style entire long messages.
-              -- For example, it's used to style the "Error:" or "[error]" label
-              -- for an error message, not the entire message.
-  | Warning   -- Should be used sparingly, not to style entire long messages.
-              -- For example, it's used to style the "Warning:" or "[warn]"
-              -- label for a warning message, not the entire message.
-  | Info      -- Should be used sparingly, not to style entire long messages.
-              -- For example, it's used to style the "[info]" label for an info
-              -- message, not the entire message.
-  | Debug     -- Should be used sparingly, not to style entire long messages.
-              -- For example, it's used to style the "[debug]" label for a debug
-              -- message, not the entire message.
-  | OtherLevel      -- Should be used sparingly, not to style entire long
-                    -- messages. For example, it's used to style the "[...]"
-                    -- label for an other log level message, not the entire
-                    -- message.
-  | Good      -- Style in a way to emphasize that it is a particularly good
-              -- thing.
-  | Shell     -- Style as a shell command, i.e. when suggesting something to the
-              -- user that should be typed in directly as written.
-  | File      -- Style as a filename. See 'Dir' for directories.
-  | Url       -- Style as a URL.
-  | Dir       -- Style as a directory name. See 'File' for files.
-  | Recommendation  -- Style used to highlight part of a recommended course of
-                    -- action.
-  | Current   -- Style in a way that emphasizes that it is related to a current
-              -- thing. For example, could be used when talking about the current
-              -- package we're processing when outputting the name of it.
-  | Target    -- TODO: figure out how to describe this
-  | Module    -- Style as a module name.
-  | PkgComponent    -- Style used to highlight the named component of a package.
-  | Secondary -- Style for secondary content. For example, it's used to style
-              -- timestamps.
-  | Highlight -- Should be used sparingly, not to style entire long messages.
-              -- For example, it's used to style the duration in a "Finished
-              -- process in ... ms" message.
+  = Error
+    -- ^ Intended to be used sparingly, not to style entire long messages. For
+    -- example, to style the @Error:@ or @[error]@ label for an error message,
+    -- not the entire message.
+  | Warning
+    -- ^ Intended to be used sparingly, not to style entire long messages. For
+    -- example, to style the @Warning:@ or @[warn]@ label for a warning message,
+    -- not the entire message.
+  | Info
+    -- ^ Intended to be used sparingly, not to style entire long messages. For
+    -- example, to style the @[info]@ label for an info message, not the entire
+    -- message.
+  | Debug
+    -- ^ Intended to be used sparingly, not to style entire long messages. For
+    -- example, to style the @[debug]@ label for a debug message, not the entire
+    -- message.
+  | OtherLevel
+    -- ^ Intended to be used sparingly, not to style entire long messages. For
+    -- example, to style the @[...]@ label for an other log level message, not
+    -- the entire message.
+  | Good
+    -- ^ Style in a way to emphasize that it is a particularly good thing.
+  | Shell
+    -- ^ Style as a shell command, i.e. when suggesting something to the user
+    -- that should be typed in directly as written.
+  | File
+    -- ^ Style as a filename. See 'Dir' for directories.
+  | Url
+    -- ^ Style as a URL.
+  | Dir
+    -- ^ Style as a directory name. See 'File' for files.
+  | Recommendation
+    -- ^ Style used to highlight part of a recommended course of action.
+  | Current
+    -- ^ Style in a way that emphasizes that it is related to a current thing.
+    -- For example, to report the current package that is being processed when
+    -- outputting the name of it.
+  | Target
+    -- ^ Style used the highlight the target of a course of action.
+  | Module
+    -- ^ Style as a module name.
+  | PkgComponent
+    -- ^ Style used to highlight the named component of a package.
+  | Secondary
+    -- ^ Style for secondary content. For example, to style timestamps.
+  | Highlight
+    -- ^ Intended to be used sparingly, not to style entire long messages. For
+    -- example, to style the duration in a @Finished process in ... ms@ message.
   deriving (Bounded, Enum, Eq, Ix, Ord, Show)
 
 -- | The first style overrides the second.
src/Text/PrettyPrint/Leijen/Extended.hs view
@@ -10,43 +10,47 @@ {-# LANGUAGE TypeFamilies               #-}
 {-# LANGUAGE UndecidableInstances       #-}
 
--- | This module re-exports some of the interface for
--- "Text.PrettyPrint.Annotated.Leijen" along with additional definitions
--- useful for stack.
+-- | This module is based, in part, on some of the interface for
+-- "Text.PrettyPrint.Annotated.Leijen".
 --
--- It defines a 'Monoid' instance for 'Doc'.
 module Text.PrettyPrint.Leijen.Extended
   (
     -- * Pretty-print typeclass
     Pretty (..)
 
-    -- * Ansi terminal Doc
-    --
-    -- See "System.Console.ANSI" for 'SGR' values to use beyond the colors
-    -- provided.
+    -- * Documents annotated by a style
   , StyleDoc (..)
   , StyleAnn(..)
-  -- hDisplayAnsi,
   , displayAnsi
   , displayPlain
   , renderDefault
 
-  -- * Selective re-exports from "Text.PrettyPrint.Annotated.Leijen"
-  --
-  -- Documentation of omissions up-to-date with @annotated-wl-pprint-0.7.0@
+    -- * Selective use of the "Text.PrettyPrint.Annotated.Leijen" interface
+    --
+    -- | Documented omissions by reference to package
+    -- @annotated-wl-pprint-0.7.0@.
 
-  -- ** Documents, parametrized by their annotations
-  --
-  -- Omitted compared to original: @putDoc, hPutDoc@
-  -- Doc,
+    -- ** Documents, parametrized by their annotations
+    --
+    -- | Omitted compared to original:
+    --
+    -- @
+    -- Doc, putDoc, hPutDoc
+    -- @
 
-  -- ** Basic combinators
-  --
-  -- Omitted compared to original: @empty, char, text, (<>)@
-  --
-  -- Instead of @text@ and @char@, use 'fromString'.
-  --
-  -- Instead of @empty@, use 'mempty'.
+    -- ** Basic combinators
+    --
+    -- | Omitted compared to the original:
+    --
+    -- @
+    -- empty, char, text, (<>)
+    -- @
+    --
+    -- Instead of @empty@, use 'mempty'.
+    --
+    -- Instead of @char@ and @text@, use 'fromString'.
+    --
+    -- A 'Monoid' instance for 'StyleDoc' is defined.
   , nest
   , line
   , linebreak
@@ -54,28 +58,35 @@   , softline
   , softbreak
 
-  -- ** Alignment
-  --
-  -- The combinators in this section can not be described by Wadler's
-  -- original combinators. They align their output relative to the
-  -- current output position - in contrast to @nest@ which always
-  -- aligns to the current nesting level. This deprives these
-  -- combinators from being \`optimal\'. In practice however they
-  -- prove to be very useful. The combinators in this section should
-  -- be used with care, since they are more expensive than the other
-  -- combinators. For example, @align@ shouldn't be used to pretty
-  -- print all top-level declarations of a language, but using @hang@
-  -- for let expressions is fine.
-  --
-  -- Omitted compared to original: @list, tupled, semiBraces@
+    -- ** Alignment
+    --
+    -- | The combinators in this section can not be described by Wadler's
+    -- original combinators. They align their output relative to the current
+    -- output position - in contrast to 'nest' which always aligns to the
+    -- current nesting level. This deprives these combinators from being
+    -- \`optimal\'. In practice however they prove to be very useful. The
+    -- combinators in this section should be used with care, since they are more
+    -- expensive than the other combinators. For example, 'align' shouldn't be
+    -- used to pretty print all top-level declarations of a language, but using
+    -- 'hang' for @let@ expressions is fine.
+    --
+    -- Omitted compared to the original:
+    --
+    -- @
+    -- list, tupled, semiBraces
+    -- @
   , align
   , hang
   , indent
   , encloseSep
 
-  -- ** Operators
-  --
-  -- Omitted compared to original: @(<$>), (</>), (<$$>), (<//>)@
+    -- ** Operators
+    --
+    -- | Omitted compared to the original:
+    --
+    -- @
+    -- (\<$\>), (\<\/\>), (\<$$\>), (\<\/\/\>)
+    -- @
   , (<+>)
 
     -- ** List combinators
@@ -103,7 +114,7 @@   , brackets
 
     -- ** Character documents
-    -- Entirely omitted:
+    -- | Entirely omitted:
     --
     -- @
     -- lparen, rparen, langle, rangle, lbrace, rbrace, lbracket, rbracket,
@@ -112,10 +123,10 @@     -- @
 
     -- ** Primitive type documents
-    -- Omitted compared to the original:
+    -- | Omitted compared to the original:
     --
     -- @
-    -- int, integer, float, double, rational, bool,
+    -- int, integer, float, double, rational, bool
     -- @
   , string
 
@@ -125,14 +136,17 @@   , styleAnn
 
   -- ** Rendering
-  -- Original entirely omitted:
+  -- | Entirely omitted:
+  --
   -- @
-  -- SimpleDoc(..), renderPretty, renderCompact, displayDecorated, displayDecoratedA, display, displayS, displayIO,
-  -- SpanList(..), displaySpans
+  -- SimpleDoc (..), renderPretty, renderCompact, displayDecorated,
+  -- displayDecoratedA, display, displayS, displayIO, SpanList (..),
+  -- displaySpans
   -- @
 
   -- ** Undocumented
-  -- Entirely omitted:
+  -- | Entirely omitted:
+  --
   -- @
   -- column, nesting, width
   -- @
@@ -198,7 +212,7 @@ --------------------------------------------------------------------------------
 -- Style Doc
 
--- |A style annotation.
+-- | A style annotation.
 newtype StyleAnn = StyleAnn (Maybe Style)
   deriving (Eq, Show, Semigroup)
 
@@ -206,15 +220,15 @@   mempty = StyleAnn Nothing
   mappend = (<>)
 
--- |A document annotated by a style
+-- | A document annotated by a style.
 newtype StyleDoc = StyleDoc { unStyleDoc :: Doc StyleAnn }
   deriving (IsString, Show)
 
--- |An ANSI code(s) annotation.
+-- | An ANSI code(s) annotation.
 newtype AnsiAnn = AnsiAnn [SGR]
   deriving (Eq, Show, Semigroup, Monoid)
 
--- |Convert a 'SimpleDoc' annotated with 'StyleAnn' to one annotated with
+-- | Convert a 'SimpleDoc' annotated with 'StyleAnn' to one annotated with
 -- 'AnsiAnn', by reference to a 'Styles'.
 toAnsiDoc :: Styles -> SimpleDoc StyleAnn -> SimpleDoc AnsiAnn
 toAnsiDoc styles = go
@@ -398,36 +412,65 @@ getSGRTag SetRGBColor{}                 = TagRGBColor
 getSGRTag SetPaletteColor{}             = TagPaletteColor
 
+-- | The document @(x \<+\> y)@ concatenates document @x@ and @y@ with a
+-- @(fromString \"\ \")@ in between. (infixr 6)
 (<+>) :: StyleDoc -> StyleDoc -> StyleDoc
 StyleDoc x <+> StyleDoc y = StyleDoc (x P.<+> y)
 
+-- | 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 <> line <> y)
+--
+-- > test = fromString "hi" <+> (fromString "nice" $$ fromString "world")
+--
+-- which will be layed out as:
+--
+-- @
+-- hi nice
+--    world
+-- @
 align :: StyleDoc -> StyleDoc
 align = StyleDoc . P.align . unStyleDoc
 
+-- | Strip annotations from a document. This is useful for re-using the textual
+-- formatting of some sub-document, but applying a different high-level
+-- annotation.
 noAnnotate :: StyleDoc -> StyleDoc
 noAnnotate = StyleDoc . P.noAnnotate . unStyleDoc
 
+-- | Document @(braces x)@ encloses document @x@ in braces, \"{\" and \"}\".
 braces :: StyleDoc -> StyleDoc
 braces = StyleDoc . P.braces . unStyleDoc
 
+-- | Document @(angles x)@ encloses document @x@ in angles, \"\<\" and \"\>\".
 angles :: StyleDoc -> StyleDoc
 angles = StyleDoc . P.angles . unStyleDoc
 
+-- | Document @(parens x)@ encloses document @x@ in parenthesis, \"(\" and
+-- \")\".
 parens :: StyleDoc -> StyleDoc
 parens = StyleDoc . P.parens . unStyleDoc
 
+-- | Document @(dquotes x)@ encloses document @x@ with double quotes '\"'.
 dquotes :: StyleDoc -> StyleDoc
 dquotes = StyleDoc . P.dquotes . unStyleDoc
 
+-- | Document @(squotes x)@ encloses document @x@ with single quotes \"'\".
 squotes :: StyleDoc -> StyleDoc
 squotes = StyleDoc . P.squotes . unStyleDoc
 
+-- | Document @(brackets x)@ encloses document @x@ in square brackets, \"[\" and
+-- \"]\".
 brackets :: StyleDoc -> StyleDoc
 brackets = StyleDoc . P.brackets . unStyleDoc
 
 -- | The document @string s@ concatenates all characters in @s@ using @line@ for
--- newline characters and @char@ for all other characters. It is used whenever
--- the text contains newline characters.
+-- newline characters and @fromString@ for all other characters. It is used
+-- whenever the text contains newline characters.
 --
 -- @since 0.1.4.0
 string :: String -> StyleDoc
@@ -439,66 +482,275 @@ annotate :: StyleAnn -> StyleDoc -> StyleDoc
 annotate a = StyleDoc . P.annotate a . unStyleDoc
 
+-- | The document @(nest i x)@ renders document @x@ with the current indentation
+-- level increased by i (See also 'hang', 'align' and 'indent').
+--
+-- >    nest 2 (fromString "hello" <> line <> fromString "world")
+-- > <> line
+-- > <> fromString "!"
+--
+-- outputs as:
+--
+-- @
+-- hello
+--   world
+-- !
+-- @
 nest :: Int -> StyleDoc -> StyleDoc
 nest a = StyleDoc . P.nest a . unStyleDoc
 
+-- | The @line@ document advances to the next line and indents to the current
+-- nesting level. Document @line@ behaves like @(fromString \" \")@ if the line
+-- break is undone by 'group'.
 line :: StyleDoc
 line = StyleDoc P.line
 
+-- | The @linebreak@ document advances to the next line and indents to the
+-- current nesting level. Document @linebreak@ behaves like 'mempty' if the line
+-- break is undone by 'group'.
 linebreak :: StyleDoc
 linebreak = StyleDoc P.linebreak
 
+-- | The document @(fill i x)@ renders document @x@. It than appends
+-- @(fromString \"\ \")@s 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 a")
+-- >         , ("nest", "Int -> Doc a -> Doc a")
+-- >         , ("linebreak", "Doc a")
+-- >         ]
+-- >
+-- > ptype (name, tp) =
+-- >   fill 6 (fromString name) <+> fromString "::" <+> fromString tp
+-- >
+-- > test = fromString "let" <+> align (vcat (map ptype types))
+--
+-- Which is layed out as:
+--
+-- @
+-- let empty  :: Doc a
+--     nest   :: Int -> Doc a -> Doc a
+--     linebreak :: Doc a
+-- @
 fill :: Int -> StyleDoc -> StyleDoc
 fill a = StyleDoc . P.fill a . unStyleDoc
 
+-- | The document @(fillBreak i x)@ first renders document @x@. It then appends
+-- @(fromString \"\ \")@s 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 (fromString name) <+> fromString "::" <+> fromString tp
+--
+-- The output will now be:
+--
+-- @
+-- let empty  :: Doc a
+--     nest   :: Int -> Doc a -> Doc a
+--     linebreak
+--            :: Doc a
+-- @
 fillBreak :: Int -> StyleDoc -> StyleDoc
 fillBreak a = StyleDoc . P.fillBreak a . unStyleDoc
 
+-- | The document @(enclose l r x)@ encloses document @x@ between documents @l@
+-- and @r@ using @(\<\>)@.
+--
+-- > enclose l r x   = l <> x <> r
 enclose :: StyleDoc -> StyleDoc -> StyleDoc -> StyleDoc
 enclose l r x = l <> x <> r
 
+-- | The document @(cat xs)@ concatenates all documents @xs@ either
+-- horizontally with @(\<\>)@, if it fits the page, or vertically with
+-- @(\<\> linebreak \<\>)@.
+--
+-- > cat xs = group (vcat xs)
 cat :: [StyleDoc] -> StyleDoc
 cat = StyleDoc . P.cat . map unStyleDoc
 
+-- | @(punctuate p xs)@ concatenates all documents in @xs@ with document @p@
+-- except for the last document.
+--
+-- > someText = map fromString ["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 'encloseSep'.)
 punctuate :: StyleDoc -> [StyleDoc] -> [StyleDoc]
 punctuate (StyleDoc x) = map StyleDoc . P.punctuate x . map unStyleDoc
 
+-- | 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 (<> softbreak <>) mempty xs
 fillCat :: [StyleDoc] -> StyleDoc
 fillCat = StyleDoc . P.fillCat . map unStyleDoc
 
+-- | The document @(hcat xs)@ concatenates all documents @xs@ horizontally with
+-- @(\<\>)@.
 hcat :: [StyleDoc] -> StyleDoc
 hcat = StyleDoc . P.hcat . map unStyleDoc
 
+-- | The document @(vcat xs)@ concatenates all documents @xs@ vertically with
+-- @(\<\> linebreak \<\>)@. If a 'group' undoes the line breaks inserted by
+-- 'vcat', all documents are directly concatenated.
 vcat :: [StyleDoc] -> StyleDoc
 vcat = StyleDoc . P.vcat . map unStyleDoc
 
+-- | The document @(sep xs)@ concatenates all documents @xs@ either horizontally
+-- with @(\<+\>)@, if it fits the page, or vertically with @(\<\> line \<\>)@.
+--
+-- > sep xs = group (vsep xs)
 sep :: [StyleDoc] -> StyleDoc
 sep = StyleDoc . P.sep . map unStyleDoc
 
+-- | The document @(vsep xs)@ concatenates all documents @xs@ vertically with
+-- @(\<\> line \<\>)@. If a 'group' undoes the line breaks inserted by 'vsep',
+-- all documents are separated with a space.
+--
+-- > someText = map fromString (words ("text to lay out"))
+-- >
+-- > test = fromString "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 = fromString "some" <+> align (vsep someText)
+--
+-- Which is printed as:
+--
+-- @
+-- some text
+--      to
+--      lay
+--      out
+-- @
 vsep :: [StyleDoc] -> StyleDoc
 vsep = StyleDoc . P.vsep . map unStyleDoc
 
+-- | The document @(hsep xs)@ concatenates all documents @xs@ horizontally with
+-- @('<+>')@.
 hsep :: [StyleDoc] -> StyleDoc
 hsep = StyleDoc . P.hsep . map unStyleDoc
 
+-- | 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 (<> softline <>) mempty xs
 fillSep :: [StyleDoc] -> StyleDoc
 fillSep = StyleDoc . P.fillSep . map unStyleDoc
 
+-- | 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 = fromString "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 :: StyleDoc -> StyleDoc -> StyleDoc -> [StyleDoc] -> StyleDoc
 encloseSep (StyleDoc x) (StyleDoc y) (StyleDoc z) =
   StyleDoc . P.encloseSep x y z . map unStyleDoc
 
+-- | The document @(indent i x)@ indents document @x@ with @i@ spaces.
+--
+-- > test = indent 4 (fillSep (map fromString
+-- >        (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 -> StyleDoc -> StyleDoc
 indent a = StyleDoc . P.indent a . unStyleDoc
 
+-- | 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 fromString
+-- >        (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 -> StyleDoc -> StyleDoc
 hang a = StyleDoc . P.hang a . unStyleDoc
 
+-- | The document @softbreak@ behaves like 'mempty' if the resulting output fits
+-- the page, otherwise it behaves like 'line'.
+--
+-- > softbreak = group linebreak
 softbreak :: StyleDoc
 softbreak = StyleDoc P.softbreak
 
+-- | The document @softline@ behaves like @(fromString \"\ \")@ if the resulting
+-- output fits the page, otherwise it behaves like 'line'.
+--
+-- > softline = group line
 softline :: StyleDoc
 softline = StyleDoc P.softline
 
+-- | 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 :: StyleDoc -> StyleDoc
 group = StyleDoc . P.group . unStyleDoc