-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A small pretty printing DSL for complex types. -- -- Please see README.md @package pretty-types @version 0.2.2.0 -- |

Type Pretty Printing

-- --

Printing Custom Types

-- -- The main usecase of this library is rendering one's own complex types -- to pretty String values, e.g. for debugging and tracing -- purposes. -- -- One way to create PrettyType documents is to define -- ToPretty instances for your types by combining the promoted -- constructors of PrettyType. -- -- If UndecidableInstances isn't holding you back, use the type -- aliases like PutStr, PutNat, PrettyInfix, etc in -- these instance definitions. -- -- ToPretty is an open type family, that converts a custom type to -- a PrettyType. -- -- showPretty eventually crafts a String value from a proxy -- to the custom type. -- -- It might be helpful to overcome egoistic needs for guaranteed compiler -- termination (i.e. allowing UndecidableInstances) in order to be able -- to use type aliases like PutStr, PutNat, etc. -- --

Example

-- -- Let's start with the output: -- --
--   +-------+-----+------------+
--   |  col 1|col 2|       col 3|
--   +-------+-----+------------+
--   |   2423|  451|       21234|
--   | 242322|   42|         n/a|
--   |      0| 4351|      623562|
--   |   4351|  n/a|         n/a|
--   |      0| 4351|      623562|
--   +-------+-----+------------+
--   
-- -- ... of rendering this table: -- --
--   type TestTable =
--     'MyTable         '[MyCol "col 1" 7, MyCol "col 2" 5, MyCol "col 3" 12]
--             '[ MyRow '[2423           ,451             ,21234]
--              , MyRow '[242322         ,42]
--              , MyRow '[0              ,4351            ,623562]
--              , MyRow '[4351]
--              , MyRow '[0              ,4351            ,623562]
--              ]
--   
-- -- ...using this function: -- --
--   prettyTestTable :: String
--   prettyTestTable = showPretty (Proxy :: Proxy TestTable)
--   
-- -- ...from these data types: -- --
--   -- | A type with a list of columns and rows.
--   data MyTable = MyTable [Type] [Type]
--   
--   -- | A row of a table, with a list of numbers, one each for every column.
--   data MyRow :: [Nat] -> Type
--   
--   -- | The column of a table. It has a width and a column title.
--   data MyCol :: Symbol -> Nat -> Type
--   
-- -- ...converted to PrettyType using this ToPretty instance: -- --
--   type instance ToPretty ('MyTable cols rows) =
--              PrettyManyIn (PutStr "+") (RowSepLine cols)
--         <$$> PrettyManyIn (PutStr "|") (TableHeading cols)
--         <$$> PrettyManyIn (PutStr "+") (RowSepLine cols)
--         <$$> PrettyHigh   (TableRows cols rows)
--         <$$> PrettyManyIn (PutStr "+") (RowSepLine cols)
--   
--   type family
--     TableHeading (cols :: [Type]) :: [PrettyType] where
--     TableHeading '[]                      = '[]
--     TableHeading (MyCol title width ': r) = PutStrW width title  ': TableHeading  r
--   
--   type family
--      RowSepLine (cols :: [Type]) :: [PrettyType] where
--      RowSepLine '[] = '[]
--      RowSepLine (MyCol title width ': r) =
--        PrettyOften width (PutStr "-") ': RowSepLine  r
--   
--   type family
--     TableRows (cols :: [Type]) (rows :: [Type]) :: [PrettyType] where
--     TableRows cols '[] = '[]
--     TableRows cols (MyRow cells ': rest ) =
--       PrettyManyIn (PutStr "|") (TableCells cols cells) ': TableRows cols rest
--   
--   type family
--     TableCells (cols :: [Type]) (cells :: [Nat]) :: [PrettyType] where
--     TableCells '[] cells = '[]
--     TableCells (MyCol title width ': cols) (value ': cells) =
--       PutNatW width value ':  TableCells cols cells
--     TableCells (MyCol title width ': cols) '[] =
--       PutStrW width "n/a" ':  TableCells cols '[]
--   
module Data.Type.Pretty -- | Pretty print either types of kind PrettyType or any other type -- with a ToPretty instance. showPretty :: forall proxy (t :: k). PrettyTypeShow (ToPretty t) => proxy t -> String -- | Create a PrettyType from a type. -- -- This is a type-level equivalent of the Show class. -- -- Write an instance of this for converting your type (preferrable of -- your kind also) to a promoted PrettyType. -- | Render a type of kind Maybe. @since 0.2.1.0 -- | A PrettyType for a string. type PutStr str = PrettySymbol PrettyUnpadded PrettyPrecise str -- | A PrettyType for a string with the exact given width. type PutStrW width str = PrettySymbol (PrettyPadded width) (PrettyPrecision width) str -- | A PrettyType for a string with a newline character at the end. type PutStrLn str = PutStr str <++> PutStr "\n" -- | A PrettyType for a number. type PutNat x = PrettyNat PrettyUnpadded PrettyPrecise PrettyDec x -- | A PrettyType for a number with a width. type PutNatW width x = PrettyNat (PrettyPadded width) PrettyPrecise PrettyDec x -- | Create PrettyType from a Nat formatted as hex number -- using lower-case letters for the hex digits. type PutHex x = PrettyNat PrettyUnpadded PrettyPrecise PrettyHex x -- | Create PrettyType from a Nat formatted as 8 bit hex -- number using lower-case letters for the hex digits. type PutHex8 x = PrettyNat PrettyUnpadded (PrettyPrecision 2) PrettyHex x -- | Create PrettyType from a Nat formatted as 16 bit hex -- number using lower-case letters for the hex digits. type PutHex16 x = PrettyNat PrettyUnpadded (PrettyPrecision 4) PrettyHex x -- | Create PrettyType from a Nat formatted as 32 bit hex -- number using lower-case letters for the hex digits. type PutHex32 x = PrettyNat PrettyUnpadded (PrettyPrecision 8) PrettyHex x -- | Create PrettyType from a Nat formatted as 64 bit hex -- number using lower-case letters for the hex digits. type PutHex64 x = PrettyNat PrettyUnpadded (PrettyPrecision 16) PrettyHex x -- | Create PrettyType from a Nat formatted as hex number -- using lower-case letters for the hex digits. type PutHeX x = PrettyNat PrettyUnpadded PrettyPrecise PrettyHexU x -- | Create PrettyType from a Nat formatted as 8 bit hex -- number using uppercase letters for the hex digits. type PutHeX8 x = PrettyNat PrettyUnpadded (PrettyPrecision 2) PrettyHexU x -- | Create PrettyType from a Nat formatted as 16 bit hex -- number using uppercase letters for the hex digits. type PutHeX16 x = PrettyNat PrettyUnpadded (PrettyPrecision 4) PrettyHexU x -- | Create PrettyType from a Nat formatted as 32 bit hex -- number using uppercase letters for the hex digits. type PutHeX32 x = PrettyNat PrettyUnpadded (PrettyPrecision 8) PrettyHexU x -- | Create PrettyType from a Nat formatted as 64 bit hex -- number using uppercase letters for the hex digits. type PutHeX64 x = PrettyNat PrettyUnpadded (PrettyPrecision 16) PrettyHexU x -- | Create PrettyType from a Nat formatted as bit -- representation, -- --
--   >>> showPretty (Proxy :: Proxy (PutBits 5))
--   "101"
--   
type PutBits x = PrettyNat PrettyUnpadded PrettyPrecise PrettyBit x -- | Create PrettyType from a Nat formatted as 8-bit bit -- representation, -- --
--   >>> showPretty (Proxy :: Proxy (PutBits8 5))
--   "00000101"
--   
type PutBits8 x = PrettyNat PrettyUnpadded (PrettyPrecision 8) PrettyBit x -- | Create PrettyType from a Nat formatted as 16-bit bit -- representation, -- --
--   >>> showPretty (Proxy :: Proxy (PutBits16 5))
--   "00000000000000101"
--   
type PutBits16 x = PrettyNat PrettyUnpadded (PrettyPrecision 16) PrettyBit x -- | Create PrettyType from a Nat formatted as 32-bit bit -- representation, -- --
--   >>> showPretty (Proxy :: Proxy (PutBits32 5))
--   "00000000000000000000000000000000101"
--   
type PutBits32 x = PrettyNat PrettyUnpadded (PrettyPrecision 32) PrettyBit x -- | Create PrettyType from a Nat formatted as 64-bit bit -- representation, -- --
--   >>> showPretty (Proxy :: Proxy (PutBits64 5))
--   "00000000000000000000000000000000000000000000000000000000000000000000101"
--   
type PutBits64 x = PrettyNat PrettyUnpadded (PrettyPrecision 64) PrettyBit x -- | A label followed by a colon and space : followed by another -- element. @since 0.2.0.0 -- --
--   >>> showPretty (Proxy :: Proxy ("foo" <:> PutStr "bar"))
--   @
--   foo: bar
--   @
--   
type (<:>) label body = PrettySuffix (PutStr ":") (PutStr label) <+> body -- | Like <:> but begin the body on a new line. @since 0.2.0.0 -- --
--   >>> showPretty (Proxy :: Proxy (PutStr "foo" <:$$> PutStr "bar"))
--   @
--   foo:
--   bar
--   @
--   
type (<:$$>) label body = PrettySuffix (PutStr ":") (PutStr label) <$$> body -- | Like '<:$$__>' but indent the body with two spaces. @since -- 0.2.0.0 -- --
--   >>> showPretty (Proxy :: Proxy (PutStr "foo" <:$$--> PutStr "bar"))
--   @
--   foo:
--     bar
--   @
--   
type (<:$$-->) label body = PrettySuffix (PutStr ":") (PutStr label) <$$--> body -- | Concatenate two PrettyType. type (<++>) l r = PrettyInfix PrettyEmpty l r -- | Concatenate two PrettyType using a PrettySpace. type (<+>) l r = PrettyInfix PrettySpace l r -- | Choose the first non-empty from two PrettyTypes. @since 0.2.0.0 type (<||>) l r = PrettyAlternative l r -- | Concatenate two PrettyType using a PrettyNewline. type (<$$>) l r = PrettyInfix PrettyNewline l r -- | Concatenate two PrettyType using a PrettyNewline and -- indent the second. @since 0.2.0.0 type (<$$-->) l r = PrettyInfix PrettyNewline l (PrettyIndent 2 r) -- | Surround a pretty with parens type PrettyParens doc = PrettySurrounded (PutStr "(") (PutStr ")") doc -- | Surround a pretty with some pretties type PrettySurrounded open close doc = (open <++> doc) <++> close -- | Combine a (type level) list of PrettyTypes next to each other -- using PrettySpace type PrettyWide docs = PrettyMany PrettySpace docs -- | Combine a (type level) list of PrettyTypes below each other -- using PrettyNewline type PrettyHigh docs = PrettyMany PrettyNewline docs -- | A combination of PrettySpace and PrettyMany, e.g.: -- --
--   >>> showPretty (Proxy :: Proxy (PrettyManyIn (PutStr "|") '[PutStr "a", PutStr "b"]))
--   "|a|b|"
--   
type PrettyManyIn sep docs = PrettySurrounded sep sep (PrettyMany sep docs) -- | Combine a (type level) list of PrettyTypes seperated by a -- seperation element. -- | Repeat a PrettyType n-times and append the copies. -- | Combinators for type documents. -- -- The basis for pretty printing is this eDSL. It is rendered via the -- PrettyTypeShow instances for its promoted constructors. -- -- Only the promoted constructors are used, only they have instances for -- that class. data PrettyType [PrettyEmpty] :: PrettyType [PrettySpace] :: PrettyType -- | Begin a newline. Always use this otherwise indentation will not work! [PrettyNewline] :: PrettyType [PrettySymbol] :: PrettyPadded -> PrettyPrecision -> Symbol -> PrettyType [PrettyNat] :: PrettyPadded -> PrettyPrecision -> PrettyNatFormat -> Nat -> PrettyType -- | Prefix the second with the first argument, but only if it (the second) -- has content. @since 0.2.0.0 [PrettyPrefix] :: PrettyType -> PrettyType -> PrettyType -- | Combine the last to arguments with the first in between them, but only -- if both have content. [PrettyInfix] :: PrettyType -> PrettyType -> PrettyType -> PrettyType -- | Add a the first argument as suffix to the second argument, but only if -- the second has content. @since 0.2.0.0 [PrettySuffix] :: PrettyType -> PrettyType -> PrettyType -- | Indentation. Prefix any line using the given number of -- PrettySpace. @since 0.2.0.0 [PrettyIndent] :: Nat -> PrettyType -> PrettyType -- | Alternative rendering, if the first document ist empty the second will -- be rendered. @since 0.2.0.0 [PrettyAlternative] :: PrettyType -> PrettyType -> PrettyType -- | Padding for PrettyTypes PrettySymbol and -- PrettyNat. data PrettyPadded -- | No minimum or fixed width [PrettyUnpadded] :: PrettyPadded -- | Pad a PrettySymbol or PrettyNat with spaces or zeros. -- NOTE PrettyNats will never be shorter than the minimum -- number of digits, regardless of this padding. [PrettyPadded] :: Nat -> PrettyPadded -- | The precision for PrettySymbol and PrettyNat. data PrettyPrecision -- | No minimum precision. [PrettyPrecise] :: PrettyPrecision -- | Precision, for Symbols the maximum width, for Nats the -- minimum digits. NOTEPrettyNats will never be shorter -- than the minimum number of digits, wheres PrettySymbols will be -- truncated if they are longer than the precision. [PrettyPrecision] :: Nat -> PrettyPrecision -- | PrettyNat formatting options. data PrettyNatFormat -- | Hexa decimal rendering: -- --
--   >>> showPretty (Proxy::Proxy (PrettyNat PrettyUnpadded PrettyPrecise PrettyHex 51966))
--   "cafe"
--   
PrettyHex :: PrettyNatFormat -- | Hexa decimal rendering (upper case): -- --
--   >>> showPretty (Proxy::Proxy (PrettyNat PrettyUnpadded PrettyPrecise PrettyHexU 51966))
--   "CAFE"
--   
PrettyHexU :: PrettyNatFormat -- | Decimal rendering: -- --
--   >>> showPretty (Proxy::Proxy (PrettyNat PrettyUnpadded PrettyPrecise PrettyHexU 51966))
--   "51966"
--   
PrettyDec :: PrettyNatFormat -- | Binary rendering: -- --
--   >>> showPretty (Proxy::Proxy (PrettyNat PrettyUnpadded PrettyPrecise PrettyHexU 51966))
--   "1100101011111110"
--   
PrettyBit :: PrettyNatFormat -- | An internal type class for rendering the types of kind -- PrettyType. class PrettyTypeShow (p :: PrettyType) where ptHasContent _ = return True -- | Given any proxy to a promoted constructor of PrettyType, -- generate a String. ptShow :: PrettyTypeShow p => proxy p -> PTM () -- | Return True if contents would be writting to the output of -- rendered via ptShow @since 0.2.0.0 ptHasContent :: PrettyTypeShow p => proxy p -> PTM Bool -- | The monad used by ptShow to keep track of indentation. @since -- 0.2.0.0 type PTM a = RWS Indentation String PTRenderState a -- | Internal; write a possibly indented string, and update the -- PTRenderState accordingly. @since 0.2.0.0 writeIndented :: String -> PTM () -- | Internal type of the indentation used by ptShow in PTM -- @since 0.2.0.0 type Indentation = Int -- | Internal state used by ptShow in PTM @since 0.2.0.0 data PTRenderState AtBeginningOfLine :: PTRenderState AlreadyIndented :: PTRenderState -- | Print nothing. -- | Print a single space character. -- | Print a single newline character. -- | Print a Symbol using the printf and the given format -- parameters. -- | Print a Nat using the printf and the given format -- parameters. -- | Concatenate two PrettyTypes. If one of them is empty print the -- other without any seperation character. -- | Prefix a PrettyType to x, but only if ptHasContent of -- x holds. -- | Add a PrettyType suffix to x, but only if ptHasContent -- holds. @since 0.2.0.0 -- | Render the first document, and if it is empty, the second @since -- 0.2.0.0 -- | Render an indented, nested type. @since 0.2.0.0 -- | Internal printf format generation. Used internally by -- PrettyTypeShow instances to generate the format string piece by -- piece with the values for the instances of e.g. PrettyPrecise, -- PrettyNatFormat, or PrettyEmpty. class PrintfArgModifier a -- | Generate a piece of a printf format string from a proxy for a -- type. toPrintfArgModifier :: PrintfArgModifier a => p a -> String -- | Translation of PrettyHex to printf format character: -- x -- | Translation of PrettyHexU to printf format character: -- X -- | Translation of PrettyDec to printf format character: -- d -- | Translation of PrettyBit to printf format character: -- b -- | Translation of PrettyUnpadded to an empty modifier string -- | Translation of PrettyPadded to a string with the numeric -- padding value. -- | Translation of PrettyPrecise to an empty modifier string -- | Translation of PrettyPadded to a string with the numeric -- precision value, prependen by a dot ".". instance Data.Type.Pretty.PrettyTypeShow 'Data.Type.Pretty.PrettyEmpty instance Data.Type.Pretty.PrettyTypeShow 'Data.Type.Pretty.PrettySpace instance Data.Type.Pretty.PrettyTypeShow 'Data.Type.Pretty.PrettyNewline instance (GHC.TypeLits.KnownSymbol t, Data.Type.Pretty.PrintfArgModifier pad, Data.Type.Pretty.PrintfArgModifier prec) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettySymbol pad prec t) instance (GHC.TypeLits.KnownNat x, Data.Type.Pretty.PrintfArgModifier fmt, Data.Type.Pretty.PrintfArgModifier pad, Data.Type.Pretty.PrintfArgModifier prec) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettyNat pad prec fmt x) instance (Data.Type.Pretty.PrettyTypeShow sep, Data.Type.Pretty.PrettyTypeShow l, Data.Type.Pretty.PrettyTypeShow r) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettyInfix sep l r) instance (Data.Type.Pretty.PrettyTypeShow sep, Data.Type.Pretty.PrettyTypeShow x) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettyPrefix sep x) instance (Data.Type.Pretty.PrettyTypeShow sep, Data.Type.Pretty.PrettyTypeShow x) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettySuffix sep x) instance (Data.Type.Pretty.PrettyTypeShow l, Data.Type.Pretty.PrettyTypeShow r) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettyAlternative l r) instance (Data.Type.Pretty.PrettyTypeShow r, GHC.TypeLits.KnownNat n) => Data.Type.Pretty.PrettyTypeShow ('Data.Type.Pretty.PrettyIndent n r) instance Data.Type.Pretty.PrintfArgModifier 'Data.Type.Pretty.PrettyHex instance Data.Type.Pretty.PrintfArgModifier 'Data.Type.Pretty.PrettyHexU instance Data.Type.Pretty.PrintfArgModifier 'Data.Type.Pretty.PrettyDec instance Data.Type.Pretty.PrintfArgModifier 'Data.Type.Pretty.PrettyBit instance Data.Type.Pretty.PrintfArgModifier 'Data.Type.Pretty.PrettyUnpadded instance GHC.TypeLits.KnownNat p => Data.Type.Pretty.PrintfArgModifier ('Data.Type.Pretty.PrettyPadded p) instance Data.Type.Pretty.PrintfArgModifier 'Data.Type.Pretty.PrettyPrecise instance GHC.TypeLits.KnownNat p => Data.Type.Pretty.PrintfArgModifier ('Data.Type.Pretty.PrettyPrecision p)