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


-- | CZipWith class and deriving via TH
--   
--   A typeclass similar to Data.Distributive, but for data parameterised
--   with a type constructor. The name comes from the resemblance of its
--   method to the regular zipWith function. The abstraction is useful for
--   example for program config handling.
@package czipwith
@version 1.0.1.4


-- | Lifted versions of the <tt><a>Functor</a></tt>,
--   <tt><tt>Pointed</tt></tt>, <tt><tt>Apply</tt></tt> and
--   <tt><a>Traversable</a></tt> classes, plus template-haskell magic to
--   automatically derive instances. "Lifted" because these classes are
--   about datatypes parameterized over a constructor (i.e. of kind <tt>(*
--   -&gt; *) -&gt; *</tt>). For example <tt>fmap :: (a -&gt; b) -&gt; f a
--   -&gt; f b</tt> becomes <tt>cMap :: (forall a . f a -&gt; g a) -&gt; c
--   f -&gt; c g</tt>.
--   
--   For the lifted version of <tt>Applicative</tt>, we focus on
--   <tt>liftA2</tt> instead of <tt>\&lt;*\&gt;</tt> as this is the only
--   way to make the lifted version work. As a consequence, the class and
--   method are named after <a>zipWith</a> because of the similarity of the
--   signatures and the semantics.
--   
--   <pre>
--   liftA2   :: Applicative f =&gt;         (g   -&gt; h   -&gt; i  ) -&gt; f g -&gt; f h -&gt; f i
--   zipWith  ::                          (g   -&gt; h   -&gt; i  ) -&gt; [g] -&gt; [h] -&gt; [i]
--   cZipWith :: CZipWith k =&gt; (forall a . g a -&gt; h a -&gt; i a) -&gt; k g -&gt; k h -&gt; k i
--   </pre>
--   
--   Types of the corresponding kind occur for example when handling
--   program configuration: When we define our an example configuration
--   type like
--   
--   <pre>
--   data MyConfig f = MyConfig
--     { flag_foo       :: f Bool
--     , flag_bar       :: f Bool
--     , flag_someLimit :: f Int
--     }
--   </pre>
--   
--   then
--   
--   <ul>
--   <li><tt>MyConfig Maybe</tt> can be used as the result-type of parsing
--   the commandline or a configuration file; it includes the option that
--   some field was not specified;</li>
--   <li><tt>MyConfig Identity</tt> can be used to represent both the
--   default configuration and the actual configuration derived from
--   defaults and the user input;</li>
--   <li><tt>MyConfig (Const Text)</tt> type to represent documentation for
--   our config, to be displayed to the user.</li>
--   </ul>
--   
--   This has the advantage that our configuration is defined in one place
--   only, so that changes are easy to make and we do not ever run into any
--   internal desynchonization of different datatypes. And once we obtained
--   the final config <tt>:: MyConfig Identity</tt>, we don't have to think
--   about <tt>Nothing</tt> cases anymore.
--   
--   <tt><tt>cPointed</tt></tt> can initialize such polymorphic containers,
--   and <tt><a>CZipWith</a></tt> further helps with this use-case, more
--   specifically the merging of input and default config: we can express
--   the merging of user/default config <tt>:: MyConfig Maybe -&gt;
--   MyConfig Identity -&gt; MyConfig Identity</tt> in terms of
--   <tt><a>cZipWith</a></tt>. The instances are simple boilerplate and
--   thus can be realized using the provided template-haskell.
--   
--   As an example for such usage, the <a>brittany</a> package uses this
--   approach together with using automatically-derived Semigroup-instances
--   that allow merging of config values (for example when commandline args
--   do not override, but are added to those settings read from config
--   file). See <a>the module containing the config type</a>.
module Data.CZipWith

-- | The "lifted Functor" class
class CFunctor c
cMap :: CFunctor c => (forall a. f a -> g a) -> c f -> c g
cMap :: (CFunctor c, CZipWith c) => (forall a. f a -> g a) -> c f -> c g

-- | The "lifted Apply" class
class CPointed c
cPoint :: CPointed c => (forall a. f a) -> c f

-- | laws:
--   
--   <ul>
--   <li><pre><a>cZipWith</a> (\x _ -&gt; x) g _ = g</pre></li>
--   <li><pre><a>cZipWith</a> (\_ y -&gt; y) _ h = h</pre></li>
--   </ul>
--   
--   This class seems to be some kind of "lifted" version of
--   <a>Applicative</a> (or rather: of <tt><tt>Apply</tt></tt>), but it
--   also seems to share an important property with the <a>Distributive</a>
--   class from the <a>distributive</a> package, even when
--   <tt><tt>Distributive</tt></tt> and <tt><a>CZipWith</a></tt> methods
--   don't appear all that similar. From the corresponding docs:
--   
--   <pre>
--   To be distributable a container will need to have a way to consistently
--   zip a potentially infinite number of copies of itself. This effectively
--   means that the holes in all values of that type, must have the same
--   cardinality, fixed sized vectors, infinite streams, functions, etc.
--   and no extra information to try to merge together.
--   </pre>
--   
--   Especially "all values of that type must have the same cardinality" is
--   true for instances of CZipWith, the only difference being that the
--   "holes" are instantiations of the <tt>f :: * -&gt; *</tt> to some
--   type, where they are simply <tt>a :: *</tt> for
--   <tt><tt>Distributive</tt></tt>.
--   
--   For many <tt><tt>Distributive</tt></tt> instances there are
--   corresponding datatypes that are instances of <tt><a>CZipWith</a></tt>
--   (although they do not seem particularly useful..), for example:
--   
--   <pre>
--   newtype CUnit a f = CUnit (f a)      -- corresponding to <tt>Identity</tt>
--   data CPair a b f = CPair (f a) (f b) -- corresponding to 'data MonoPair a = MonoPair a a'
--                                        -- (Pair being a trivial fixed-size vector example)
--   data CStream a f = CStream (f a) (CStream a f) -- corresponding to an infinite stream
--   </pre>
class CZipWith (k :: (Type -> Type) -> Type)

-- | zipWith on constructors instead of values.
cZipWith :: CZipWith k => (forall a. g a -> h a -> i a) -> k g -> k h -> k i

-- | Where <a>CZipWith</a> is a "lifted <tt>Apply</tt>", this is a "lifted
--   <a>Traversable</a>".
--   
--   laws:
--   
--   <ul>
--   <li><i><i>naturality</i></i> <tt>t . <a>cTraverse</a> f =
--   <a>cTraverse</a> (t . f)</tt> for every applicative transformation
--   <tt>t</tt></li>
--   <li><i><i>identity</i></i> <tt><a>cTraverse</a> Identity =
--   Identity</tt></li>
--   <li><i><i>composition</i></i> <tt><a>cTraverse</a> (Compose .
--   <a>fmap</a> g . f) = Compose . <a>fmap</a> (<a>cTraverse</a> g) .
--   <a>cTraverse</a> f</tt></li>
--   </ul>
--   
--   and <tt>cZipWithM f k l</tt> must behave like <tt>cTraverse getCompose
--   (cZipWith (x y -&gt; Compose (f x y)) k l)</tt>
class CZipWith c => CZipWithM c
cTraverse :: (CZipWithM c, Applicative m) => (forall a. f a -> m (g a)) -> c f -> m (c g)
cZipWithM :: (CZipWithM c, Applicative m) => (forall a. f a -> g a -> m (h a)) -> c f -> c g -> m (c h)

-- | The equivalent of <tt><a>Traversable</a></tt>'s
--   <tt><a>sequence</a></tt>/<tt><a>sequenceA</a></tt>
cSequence :: Applicative m => CZipWithM c => c (Compose m f) -> m (c f)

-- | Derives a <tt>cPointed</tt> instance for a datatype of kind <tt>(*
--   -&gt; *) -&gt; *</tt>.
--   
--   Requires that for this datatype (we shall call its argument <tt>f :: *
--   -&gt; *</tt> here)
--   
--   <ul>
--   <li>there is exactly one constructor;</li>
--   <li>all fields in the one constructor are either of the form <tt>f
--   x</tt> for some <tt>x</tt> or of the form <tt>X f</tt> for some type
--   <tt>X</tt> where there is an <tt>instance cPointed X</tt>.</li>
--   </ul>
--   
--   For example, the following would be valid usage:
--   
--   <pre>
--   data A f = A
--     { a_str  :: f String
--     , a_bool :: f Bool
--     }
--   
--   data B f = B
--     { b_int   :: f Int
--     , b_float :: f Float
--     , b_a     :: A f
--     }
--   
--   derivecPointed ''A
--   derivecPointed ''B
--   </pre>
--   
--   This produces the following instances:
--   
--   <pre>
--   instance cPointed A where
--     cPoint f = A f f
--   
--   instance cPointed B where
--     cPoint f = B f f (cPoint f f)
--   </pre>
deriveCPointed :: Name -> DecsQ

-- | Derives a <a>CZipWith</a> instance for a datatype of kind <tt>(* -&gt;
--   *) -&gt; *</tt>.
--   
--   Requires that for this datatype (we shall call its argument <tt>f :: *
--   -&gt; *</tt> here)
--   
--   <ul>
--   <li>there is exactly one constructor;</li>
--   <li>all fields in the one constructor are either of the form <tt>f
--   x</tt> for some <tt>x</tt> or of the form <tt>X f</tt> for some type
--   <tt>X</tt> where there is an <tt>instance CZipWith X</tt>.</li>
--   </ul>
--   
--   For example, the following would be valid usage:
--   
--   <pre>
--   data A f = A
--     { a_str  :: f String
--     , a_bool :: f Bool
--     }
--   
--   data B f = B
--     { b_int   :: f Int
--     , b_float :: f Float
--     , b_a     :: A f
--     }
--   
--   deriveCZipWith ''An
--   deriveCZipWith ''B
--   </pre>
--   
--   This produces the following instances:
--   
--   <pre>
--   instance CZipWith A where
--     cZipWith f (A x1 x2) (A y1 y2) = A (f x1 y1) (f x2 y2)
--   
--   instance CZipWith B wheren
--     cZipWith f (B x1 x2 x3) (B y1 y2 y3) =
--       B (f x1 y1) (f x2 y2) (cZipWith f x3 y3)
--   </pre>
deriveCZipWith :: Name -> DecsQ

-- | Derives a <a>CZipWithM</a> instance for a datatype of kind <tt>(*
--   -&gt; *) -&gt; *</tt>.
--   
--   Requires that for this datatype (we shall call its argument <tt>f :: *
--   -&gt; *</tt> here)
--   
--   <ul>
--   <li>there is exactly one constructor;</li>
--   <li>all fields in the one constructor are either of the form <tt>f
--   x</tt> for some <tt>x</tt> or of the form <tt>X f</tt> for some type
--   <tt>X</tt> where there is an <tt>instance CZipWithM X</tt>.</li>
--   </ul>
--   
--   For example, the following would be valid usage:
--   
--   <pre>
--   data A f = A
--     { a_str  :: f String
--     , a_bool :: f Bool
--     }
--   
--   data B f = B
--     { b_int   :: f Int
--     , b_float :: f Float
--     , b_a     :: A f
--     }
--   
--   deriveCZipWithM ''A
--   deriveCZipWithM ''B
--   </pre>
--   
--   This produces the following instances:
--   
--   <pre>
--   instance CZipWithM A where
--     cZipWithM f (A x1 x2) (A y1 y2) = A &lt;$&gt; f x1 y1 &lt;*&gt; f x2 y2
--   
--   instance CZipWith B where
--     cZipWithM f (B x1 x2 x3) (B y1 y2 y3) =
--       B &lt;$&gt; f x1 y1 &lt;*&gt; f x2 y2 &lt;*&gt; cZipWithM f x3 y3
--   </pre>
deriveCZipWithM :: Name -> DecsQ
