-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Generic types and functions for columnar encoding and decoding
--   
--   The <a>colonnade</a> package provides a way to talk about columnar
--   encodings and decodings of data. This package provides very general
--   types and does not provide a way for the end-user to actually apply
--   the columnar encodings they build to data. Most users will also want
--   to one a companion packages that provides (1) a content type and (2)
--   functions for feeding data into a columnar encoding:
--   
--   <ul>
--   <li><a>lucid-colonnade</a> for <a>lucid</a> html tables</li>
--   <li><a>blaze-colonnade</a> for <a>blaze</a> html tables</li>
--   <li><a>reflex-dom-colonnade</a> for reactive `reflex-dom` tables</li>
--   <li><a>yesod-colonnade</a> for <a>yesod</a> widgets</li>
--   <li><a>siphon</a> for encoding and decoding CSVs</li>
--   </ul>
@package colonnade
@version 1.2.0.1


-- | Most users of this library do not need this module. The functions here
--   are used to build functions that apply a <a>Colonnade</a> to a
--   collection of values, building a table from them. Ultimately, a
--   function that applies a <tt>Colonnade Headed MyCell a</tt> to data
--   will have roughly the following type:
--   
--   <pre>
--   myTableRenderer :: Foldable g =&gt; Colonnade Headed MyCell a -&gt; g a -&gt; MyContent
--   </pre>
--   
--   In the companion packages <tt>yesod-colonnade</tt> and
--   <tt>reflex-dom-colonnade</tt>, functions with similar type signatures
--   are readily available. These packages use the functions provided here
--   in the implementations of their rendering functions. It is recommended
--   that users who believe they may need this module look at the source of
--   the companion packages to see an example of how this module's
--   functions are used. Other backends are encouraged to use these
--   functions to build monadic or monoidal content from a
--   <a>Colonnade</a>.
--   
--   The functions exported here take a <a>Colonnade</a> and convert it to
--   a fragment of content. The functions whose names start with
--   <tt>row</tt> take at least a <tt>Colonnade f c a</tt> and an
--   <tt>a</tt> value to generate a row of content. The functions whose
--   names start with <tt>header</tt> need the <tt>Colonnade f c a</tt> but
--   not an <tt>a</tt> value since a value is not needed to build a header.
module Colonnade.Encode

-- | An columnar encoding of <tt>a</tt>. The type variable <tt>h</tt>
--   determines what is present in each column in the header row. It is
--   typically instantiated to <a>Headed</a> and occasionally to
--   <a>Headless</a>. There is nothing that restricts it to these two
--   types, although they satisfy the majority of use cases. The type
--   variable <tt>c</tt> is the content type. This can be <tt>Text</tt>,
--   <tt>String</tt>, or <tt>ByteString</tt>. In the companion libraries
--   <tt>reflex-dom-colonnade</tt> and <tt>yesod-colonnade</tt>, additional
--   types that represent HTML with element attributes are provided that
--   serve as the content type. Presented more visually:
--   
--   <pre>
--               +---- Value consumed to build a row
--               |
--               v
--   Colonnade h a c
--             ^   ^
--             |   |
--             |   +-- Content (Text, ByteString, Html, etc.)
--             |
--             +------ Headedness (Headed or Headless)
--   </pre>
--   
--   Internally, a <a>Colonnade</a> is represented as a <a>Vector</a> of
--   individual column encodings. It is possible to use any collection type
--   with <tt>Alternative</tt> and <a>Foldable</a> instances. However,
--   <a>Vector</a> was chosen to optimize the data structure for the use
--   case of building the structure once and then folding over it many
--   times. It is recommended that <a>Colonnade</a>s are defined at the
--   top-level so that GHC avoids reconstructing them every time they are
--   used.
newtype Colonnade h a c
Colonnade :: Vector (OneColonnade h a c) -> Colonnade h a c
[getColonnade] :: Colonnade h a c -> Vector (OneColonnade h a c)

-- | Encodes a header and a cell.
data OneColonnade h a c
OneColonnade :: !(h c) -> !(a -> c) -> OneColonnade h a c
[oneColonnadeHead] :: OneColonnade h a c -> !(h c)
[oneColonnadeEncode] :: OneColonnade h a c -> !(a -> c)

-- | As the first argument to the <a>Colonnade</a> type constructor, this
--   indictates that the columnar encoding has a header. This type is
--   isomorphic to <tt>Identity</tt> but is given a new name to clarify its
--   intent:
--   
--   <pre>
--   example :: Colonnade Headed Foo Text
--   </pre>
--   
--   The term <tt>example</tt> represents a columnar encoding of
--   <tt>Foo</tt> in which the columns have headings.
newtype Headed a
Headed :: a -> Headed a
[getHeaded] :: Headed a -> a

-- | As the first argument to the <a>Colonnade</a> type constructor, this
--   indictates that the columnar encoding does not have a header. This
--   type is isomorphic to <tt>Proxy</tt> but is given a new name to
--   clarify its intent:
--   
--   <pre>
--   example :: Colonnade Headless Foo Text
--   </pre>
--   
--   The term <tt>example</tt> represents a columnar encoding of
--   <tt>Foo</tt> in which the columns do not have headings.
data Headless a
Headless :: Headless a
data Sized sz f a
Sized :: !sz -> !(f a) -> Sized sz f a
[sizedSize] :: Sized sz f a -> !sz
[sizedContent] :: Sized sz f a -> !(f a)
newtype ExtractForall h
ExtractForall :: forall a. h a -> a -> ExtractForall h
[runExtractForall] :: ExtractForall h -> forall a. h a -> a

-- | This class communicates that a container holds either zero elements or
--   one element. Furthermore, all inhabitants of the type must hold the
--   same number of elements. Both <a>Headed</a> and <a>Headless</a> have
--   instances. The following law accompanies any instances:
--   
--   <pre>
--   maybe x (\f -&gt; f (headednessPure x)) headednessContents == x
--   todo: come up with another law that relates to Traversable
--   </pre>
--   
--   Consequently, there is no instance for <a>Maybe</a>, which cannot
--   satisfy the laws since it has inhabitants which hold different numbers
--   of elements. <a>Nothing</a> holds 0 elements and <a>Just</a> holds 1
--   element.
class Headedness h
headednessPure :: Headedness h => a -> h a
headednessExtract :: Headedness h => Maybe (h a -> a)
headednessExtractForall :: Headedness h => Maybe (ExtractForall h)

-- | Consider providing a variant the produces a list instead. It may allow
--   more things to get inlined in to a loop.
row :: (c1 -> c2) -> Colonnade f a c1 -> a -> Vector c2
rowMonadic :: (Monad m, Monoid b) => Colonnade f a c -> (c -> m b) -> a -> m b
rowMonadic_ :: Monad m => Colonnade f a c -> (c -> m b) -> a -> m ()
rowMonadicWith :: (Monad m) => b -> (b -> b -> b) -> Colonnade f a c -> (c -> m b) -> a -> m b
rowMonoidal :: Monoid m => Colonnade h a c -> (c -> m) -> a -> m
rowMonoidalHeader :: Monoid m => Colonnade h a c -> (h c -> c -> m) -> a -> m
header :: (c1 -> c2) -> Colonnade Headed a c1 -> Vector c2
headerMonadic :: (Monad m, Monoid b) => Colonnade Headed a c -> (c -> m b) -> m b
headerMonadic_ :: (Monad m) => Colonnade Headed a c -> (c -> m b) -> m ()

-- | This function is a helper for abusing <a>Foldable</a> to optionally
--   render a header. Its future is uncertain.
headerMonadicGeneral :: (Monad m, Monoid b, Foldable h) => Colonnade h a c -> (c -> m b) -> m b
headerMonadicGeneral_ :: (Monad m, Headedness h) => Colonnade h a c -> (c -> m b) -> m ()
headerMonoidalGeneral :: (Monoid m, Foldable h) => Colonnade h a c -> (c -> m) -> m
headerMonoidalFull :: Monoid m => Colonnade h a c -> (h c -> m) -> m
bothMonadic_ :: Monad m => Colonnade Headed a c -> (c -> c -> m b) -> a -> m ()
sizeColumns :: (Foldable f, Foldable h) => (c -> Int) -> f a -> Colonnade h a c -> Colonnade (Sized (Maybe Int) h) a c
data Cornice h (p :: Pillar) a c
[CorniceBase] :: !(Colonnade h a c) -> Cornice h Base a c
[CorniceCap] :: {-# UNPACK #-} !(Vector (OneCornice (Cornice h) p a c)) -> Cornice h (Cap p) a c
data AnnotatedCornice sz h (p :: Pillar) a c
[AnnotatedCorniceBase] :: !sz -> !(Colonnade (Sized sz h) a c) -> AnnotatedCornice sz h Base a c
[AnnotatedCorniceCap] :: !sz -> {-# UNPACK #-} !(Vector (OneCornice (AnnotatedCornice sz h) p a c)) -> AnnotatedCornice sz h (Cap p) a c
data OneCornice k (p :: Pillar) a c
OneCornice :: !c -> !(k p a c) -> OneCornice k a c
[oneCorniceHead] :: OneCornice k a c -> !c
[oneCorniceBody] :: OneCornice k a c -> !(k p a c)

-- | Isomorphic to the natural numbers. Only the promoted version of this
--   type is used.
data Pillar
Cap :: !Pillar -> Pillar
Base :: Pillar
class ToEmptyCornice (p :: Pillar)
toEmptyCornice :: ToEmptyCornice p => Cornice h p a c
data Fascia (p :: Pillar) r
[FasciaBase] :: !r -> Fascia Base r
[FasciaCap] :: !r -> Fascia p r -> Fascia (Cap p) r
annotate :: Cornice Headed p a c -> AnnotatedCornice (Maybe Int) Headed p a c
annotateFinely :: Foldable f => (Int -> Int -> Int) -> (Int -> Int) -> (c -> Int) -> f a -> Cornice Headed p a c -> AnnotatedCornice (Maybe Int) Headed p a c

-- | This is an O(1) operation, sort of
size :: AnnotatedCornice sz h p a c -> sz
endow :: forall p a c. (c -> c -> c) -> Cornice Headed p a c -> Colonnade Headed a c
discard :: Cornice h p a c -> Colonnade h a c
headersMonoidal :: forall sz r m c p a h. (Monoid m, Headedness h) => Maybe (Fascia p r, r -> m -> m) -> [(sz -> c -> m, m -> m)] -> AnnotatedCornice sz h p a c -> m
uncapAnnotated :: forall sz p a c h. AnnotatedCornice sz h p a c -> Colonnade (Sized sz h) a c
instance GHC.Base.Functor (k p a) => GHC.Base.Functor (Colonnade.Encode.OneCornice k p a)
instance GHC.Base.Functor h => GHC.Base.Functor (Colonnade.Encode.Colonnade h a)
instance GHC.Base.Monoid (Colonnade.Encode.Colonnade h a c)
instance GHC.Base.Functor h => GHC.Base.Functor (Colonnade.Encode.OneColonnade h a)
instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Colonnade.Encode.Sized sz f)
instance GHC.Base.Functor f => GHC.Base.Functor (Colonnade.Encode.Sized sz f)
instance Data.Foldable.Foldable Colonnade.Encode.Headless
instance GHC.Read.Read (Colonnade.Encode.Headless a)
instance GHC.Show.Show (Colonnade.Encode.Headless a)
instance GHC.Base.Functor Colonnade.Encode.Headless
instance GHC.Classes.Ord (Colonnade.Encode.Headless a)
instance GHC.Classes.Eq (Colonnade.Encode.Headless a)
instance Data.Foldable.Foldable Colonnade.Encode.Headed
instance GHC.Read.Read a => GHC.Read.Read (Colonnade.Encode.Headed a)
instance GHC.Show.Show a => GHC.Show.Show (Colonnade.Encode.Headed a)
instance GHC.Base.Functor Colonnade.Encode.Headed
instance GHC.Classes.Ord a => GHC.Classes.Ord (Colonnade.Encode.Headed a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Colonnade.Encode.Headed a)
instance Colonnade.Encode.Headedness Colonnade.Encode.Headed
instance Colonnade.Encode.Headedness Colonnade.Encode.Headless
instance Colonnade.Encode.ToEmptyCornice 'Colonnade.Encode.Base
instance Colonnade.Encode.ToEmptyCornice ('Colonnade.Encode.Cap p)
instance Colonnade.Encode.ToEmptyCornice p => GHC.Base.Monoid (Colonnade.Encode.Cornice h p a c)
instance GHC.Base.Functor h => GHC.Base.Functor (Colonnade.Encode.Cornice h p a)
instance GHC.Base.Functor h => Data.Profunctor.Unsafe.Profunctor (Colonnade.Encode.Cornice h p)
instance GHC.Base.Semigroup (Colonnade.Encode.Cornice h p a c)
instance GHC.Base.Functor h => Data.Profunctor.Unsafe.Profunctor (Colonnade.Encode.Colonnade h)
instance GHC.Base.Semigroup (Colonnade.Encode.Colonnade h a c)
instance GHC.Base.Functor h => Data.Profunctor.Unsafe.Profunctor (Colonnade.Encode.OneColonnade h)
instance GHC.Base.Applicative Colonnade.Encode.Headless
instance Data.Functor.Contravariant.Contravariant Colonnade.Encode.Headless
instance GHC.Base.Applicative Colonnade.Encode.Headed


-- | Build backend-agnostic columnar encodings that can be used to
--   visualize tabular data.
module Colonnade

-- | An columnar encoding of <tt>a</tt>. The type variable <tt>h</tt>
--   determines what is present in each column in the header row. It is
--   typically instantiated to <a>Headed</a> and occasionally to
--   <a>Headless</a>. There is nothing that restricts it to these two
--   types, although they satisfy the majority of use cases. The type
--   variable <tt>c</tt> is the content type. This can be <tt>Text</tt>,
--   <tt>String</tt>, or <tt>ByteString</tt>. In the companion libraries
--   <tt>reflex-dom-colonnade</tt> and <tt>yesod-colonnade</tt>, additional
--   types that represent HTML with element attributes are provided that
--   serve as the content type. Presented more visually:
--   
--   <pre>
--               +---- Value consumed to build a row
--               |
--               v
--   Colonnade h a c
--             ^   ^
--             |   |
--             |   +-- Content (Text, ByteString, Html, etc.)
--             |
--             +------ Headedness (Headed or Headless)
--   </pre>
--   
--   Internally, a <a>Colonnade</a> is represented as a <a>Vector</a> of
--   individual column encodings. It is possible to use any collection type
--   with <tt>Alternative</tt> and <a>Foldable</a> instances. However,
--   <a>Vector</a> was chosen to optimize the data structure for the use
--   case of building the structure once and then folding over it many
--   times. It is recommended that <a>Colonnade</a>s are defined at the
--   top-level so that GHC avoids reconstructing them every time they are
--   used.
data Colonnade h a c

-- | As the first argument to the <a>Colonnade</a> type constructor, this
--   indictates that the columnar encoding has a header. This type is
--   isomorphic to <tt>Identity</tt> but is given a new name to clarify its
--   intent:
--   
--   <pre>
--   example :: Colonnade Headed Foo Text
--   </pre>
--   
--   The term <tt>example</tt> represents a columnar encoding of
--   <tt>Foo</tt> in which the columns have headings.
newtype Headed a
Headed :: a -> Headed a
[getHeaded] :: Headed a -> a

-- | As the first argument to the <a>Colonnade</a> type constructor, this
--   indictates that the columnar encoding does not have a header. This
--   type is isomorphic to <tt>Proxy</tt> but is given a new name to
--   clarify its intent:
--   
--   <pre>
--   example :: Colonnade Headless Foo Text
--   </pre>
--   
--   The term <tt>example</tt> represents a columnar encoding of
--   <tt>Foo</tt> in which the columns do not have headings.
data Headless a
Headless :: Headless a

-- | This class communicates that a container holds either zero elements or
--   one element. Furthermore, all inhabitants of the type must hold the
--   same number of elements. Both <a>Headed</a> and <a>Headless</a> have
--   instances. The following law accompanies any instances:
--   
--   <pre>
--   maybe x (\f -&gt; f (headednessPure x)) headednessContents == x
--   todo: come up with another law that relates to Traversable
--   </pre>
--   
--   Consequently, there is no instance for <a>Maybe</a>, which cannot
--   satisfy the laws since it has inhabitants which hold different numbers
--   of elements. <a>Nothing</a> holds 0 elements and <a>Just</a> holds 1
--   element.
class Headedness h
headednessPure :: Headedness h => a -> h a
headednessExtract :: Headedness h => Maybe (h a -> a)
headednessExtractForall :: Headedness h => Maybe (ExtractForall h)

-- | A single column with a header.
headed :: c -> (a -> c) -> Colonnade Headed a c

-- | A single column without a header.
headless :: (a -> c) -> Colonnade Headless a c

-- | A single column with any kind of header. This is not typically needed.
singleton :: h c -> (a -> c) -> Colonnade h a c

-- | Lift a column over a <a>Maybe</a>. For example, if some people have
--   houses and some do not, the data that pairs them together could be
--   represented as:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let owners :: [(Person,Maybe House)]
--       owners =
--         [ (Person "Jordan" 18, Nothing)
--         , (Person "Ruth" 25, Just (House Red 125000))
--         , (Person "Sonia" 12, Just (House Green 145000))
--         ]
--   :}
--   </pre>
--   
--   The column encodings defined earlier can be reused with the help of
--   <a>fromMaybe</a>:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let colOwners :: Colonnade Headed (Person,Maybe House) String
--       colOwners = mconcat
--         [ lmap fst colPerson
--         , lmap snd (fromMaybe "" colHouse)
--         ]
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr (ascii colOwners owners)
--   +--------+-----+-------+---------+
--   | Name   | Age | Color | Price   |
--   +--------+-----+-------+---------+
--   | Jordan | 18  |       |         |
--   | Ruth   | 25  | Red   | $125000 |
--   | Sonia  | 12  | Green | $145000 |
--   +--------+-----+-------+---------+
--   </pre>
fromMaybe :: c -> Colonnade f a c -> Colonnade f (Maybe a) c

-- | Convert a collection of <tt>b</tt> values into a columnar encoding of
--   the same size. Suppose we decide to show a house's color by putting a
--   check mark in the column corresponding to the color instead of by
--   writing out the name of the color:
--   
--   <pre>
--   &gt;&gt;&gt; let allColors = [Red,Green,Blue]
--   
--   &gt;&gt;&gt; let encColor = columns (\c1 c2 -&gt; if c1 == c2 then "✓" else "") (Headed . show) allColors
--   
--   &gt;&gt;&gt; :t encColor
--   encColor :: Colonnade Headed Color [Char]
--   
--   &gt;&gt;&gt; let encHouse = headed "Price" (showDollar . price) &lt;&gt; lmap color encColor
--   
--   &gt;&gt;&gt; :t encHouse
--   encHouse :: Colonnade Headed House [Char]
--   
--   &gt;&gt;&gt; putStr (ascii encHouse houses)
--   +---------+-----+-------+------+
--   | Price   | Red | Green | Blue |
--   +---------+-----+-------+------+
--   | $170000 |     | ✓     |      |
--   | $115000 |     |       | ✓    |
--   | $150000 |     | ✓     |      |
--   +---------+-----+-------+------+
--   </pre>
columns :: Foldable g => (b -> a -> c) -> (b -> f c) -> g b -> Colonnade f a c
bool :: f c -> (a -> Bool) -> (a -> c) -> (a -> c) -> Colonnade f a c

-- | Replace the contents of cells in rows whose values satisfy the given
--   predicate. Header content is unaffected.
replaceWhen :: c -> (a -> Bool) -> Colonnade f a c -> Colonnade f a c

-- | Modify the contents of cells in rows whose values satisfy the given
--   predicate. Header content is unaffected. With an HTML backend, this
--   can be used to strikethrough the contents of cells with data that is
--   considered invalid.
modifyWhen :: (c -> c) -> (a -> Bool) -> Colonnade f a c -> Colonnade f a c

-- | Map over the content in the header. This is similar performing
--   <a>fmap</a> on a <a>Colonnade</a> except that the body content is
--   unaffected.
mapHeaderContent :: Functor h => (c -> c) -> Colonnade h a c -> Colonnade h a c

-- | Map over the header type of a <a>Colonnade</a>.
mapHeadedness :: (forall x. h x -> h' x) -> Colonnade h a c -> Colonnade h' a c

-- | Remove the heading from a <a>Colonnade</a>.
toHeadless :: Colonnade h a c -> Colonnade Headless a c
data Cornice h (p :: Pillar) a c

-- | Isomorphic to the natural numbers. Only the promoted version of this
--   type is used.
data Pillar
Cap :: !Pillar -> Pillar
Base :: Pillar
data Fascia (p :: Pillar) r
[FasciaBase] :: !r -> Fascia Base r
[FasciaCap] :: !r -> Fascia p r -> Fascia (Cap p) r

-- | Augment a <a>Colonnade</a> with a header spans over all of the
--   existing headers. This is best demonstrated by example. Let's consider
--   how we might encode a pairing of the people and houses from the
--   initial example:
--   
--   <pre>
--   &gt;&gt;&gt; let personHomePairs = zip people houses
--   
--   &gt;&gt;&gt; let colPersonFst = lmap fst colPerson
--   
--   &gt;&gt;&gt; let colHouseSnd = lmap snd colHouse
--   
--   &gt;&gt;&gt; putStr (ascii (colPersonFst &lt;&gt; colHouseSnd) personHomePairs)
--   +-------+-----+-------+---------+
--   | Name  | Age | Color | Price   |
--   +-------+-----+-------+---------+
--   | David | 63  | Green | $170000 |
--   | Ava   | 34  | Blue  | $115000 |
--   | Sonia | 12  | Green | $150000 |
--   +-------+-----+-------+---------+
--   </pre>
--   
--   This tabular encoding leaves something to be desired. The heading not
--   indicate that the name and age refer to a person and that the color
--   and price refer to a house. Without reaching for <a>Cornice</a>, we
--   can still improve this situation with <a>mapHeaderContent</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let colPersonFst' = mapHeaderContent ("Person " ++) colPersonFst
--   
--   &gt;&gt;&gt; let colHouseSnd' = mapHeaderContent ("House " ++) colHouseSnd
--   
--   &gt;&gt;&gt; putStr (ascii (colPersonFst' &lt;&gt; colHouseSnd') personHomePairs)
--   +-------------+------------+-------------+-------------+
--   | Person Name | Person Age | House Color | House Price |
--   +-------------+------------+-------------+-------------+
--   | David       | 63         | Green       | $170000     |
--   | Ava         | 34         | Blue        | $115000     |
--   | Sonia       | 12         | Green       | $150000     |
--   +-------------+------------+-------------+-------------+
--   </pre>
--   
--   This is much better, but for longer tables, the redundancy of
--   prefixing many column headers can become annoying. The solution that a
--   <a>Cornice</a> offers is to nest headers:
--   
--   <pre>
--   &gt;&gt;&gt; let cor = mconcat [cap "Person" colPersonFst, cap "House" colHouseSnd]
--   
--   &gt;&gt;&gt; :t cor
--   cor :: Cornice Headed ('Cap 'Base) (Person, House) [Char]
--   
--   &gt;&gt;&gt; putStr (asciiCapped cor personHomePairs)
--   +-------------+-----------------+
--   | Person      | House           |
--   +-------+-----+-------+---------+
--   | Name  | Age | Color | Price   |
--   +-------+-----+-------+---------+
--   | David | 63  | Green | $170000 |
--   | Ava   | 34  | Blue  | $115000 |
--   | Sonia | 12  | Green | $150000 |
--   +-------+-----+-------+---------+
--   </pre>
cap :: c -> Colonnade h a c -> Cornice h (Cap Base) a c

-- | Add another cap to a cornice. There is no limit to how many times this
--   can be applied:
--   
--   <pre>
--   &gt;&gt;&gt; data Day = Weekday | Weekend deriving (Show)
--   
--   &gt;&gt;&gt; :{
--   let cost :: Int -&gt; Day -&gt; String
--       cost base w = case w of
--         Weekday -&gt; showDollar base
--         Weekend -&gt; showDollar (base + 1)
--       colStandard = foldMap (\c -&gt; headed c (cost 8)) ["Yt","Ad","Sr"]
--       colSpecial = mconcat [headed "Stud" (cost 6), headed "Mltry" (cost 7)]
--       corStatus = mconcat
--         [ cap "Standard" colStandard
--         , cap "Special" colSpecial
--         ] 
--       corShowtime = mconcat
--         [ recap "" (cap "" (headed "Day" show))
--         , foldMap (\c -&gt; recap c corStatus) ["Matinee","Evening"]
--         ]
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr (asciiCapped corShowtime [Weekday,Weekend])
--   +---------+-----------------------------+-----------------------------+
--   |         | Matinee                     | Evening                     |
--   +---------+--------------+--------------+--------------+--------------+
--   |         | Standard     | Special      | Standard     | Special      |
--   +---------+----+----+----+------+-------+----+----+----+------+-------+
--   | Day     | Yt | Ad | Sr | Stud | Mltry | Yt | Ad | Sr | Stud | Mltry |
--   +---------+----+----+----+------+-------+----+----+----+------+-------+
--   | Weekday | $8 | $8 | $8 | $6   | $7    | $8 | $8 | $8 | $6   | $7    |
--   | Weekend | $9 | $9 | $9 | $7   | $8    | $9 | $9 | $9 | $7   | $8    |
--   +---------+----+----+----+------+-------+----+----+----+------+-------+
--   </pre>
recap :: c -> Cornice h p a c -> Cornice h (Cap p) a c

-- | Render a collection of rows as an ascii table. The table's columns are
--   specified by the given <a>Colonnade</a>. This implementation is
--   inefficient and does not provide any wrapping behavior. It is provided
--   so that users can try out <tt>colonnade</tt> in ghci and so that
--   <tt>doctest</tt> can verify example code in the haddocks.
ascii :: Foldable f => Colonnade Headed a String -> f a -> String
asciiCapped :: Foldable f => Cornice Headed p a String -> f a -> String
