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


-- | Classes for working with types that can change clothes.
--   
--   Types that are parametric on a functor are like Barbies that have an
--   outfit for each role. This package provides the basic abstractions to
--   work with them comfortably.
@package barbies
@version 2.0.4.0


-- | Generalize the standard two-functor <a>Product</a> to the product of
--   <tt>n</tt>-functors. Intuitively, this means:
--   
--   <pre>
--   <a>Product</a> f g a ~~ (f a, g a)
--   
--   <a>Prod</a> '[]        a ~~  Const () a
--   <a>Prod</a> '[f]       a ~~ (f a)
--   <a>Prod</a> '[f, g]    a ~~ (f a, g a)
--   <a>Prod</a> '[f, g, h] a ~~ (f a, g a, h a)
--       ⋮
--   </pre>

-- | <i>Deprecated: The module is no longer part of the main api and will
--   be removed </i>
module Data.Functor.Prod

-- | Product of n functors.
data Prod :: [k -> Type] -> k -> Type
[Unit] :: Prod '[] a
[Cons] :: f a -> Prod fs a -> Prod (f ': fs) a

-- | The unit of the product.
zeroTuple :: Prod '[] a

-- | Lift a functor to a 1-tuple.
oneTuple :: f a -> Prod '[f] a

-- | Conversion from a standard <a>Product</a>
fromProduct :: Product f g a -> Prod '[f, g] a

-- | Conversion to a standard <a>Product</a>
toProduct :: Prod '[f, g] a -> Product f g a

-- | Flat product of products.
prod :: Prod ls a -> Prod rs a -> Prod (ls ++ rs) a

-- | Like <a>uncurry</a> but using <a>Prod</a> instead of pairs. Can be
--   thought of as a family of functions:
--   
--   <pre>
--   <a>uncurryn</a> :: r a -&gt; <a>Prod</a> '[] a
--   <a>uncurryn</a> :: (f a -&gt; r a) -&gt; <a>Prod</a> '[f] a
--   <a>uncurryn</a> :: (f a -&gt; g a -&gt; r a) -&gt; <a>Prod</a> '[f, g] a
--   <a>uncurryn</a> :: (f a -&gt; g a -&gt; h a -&gt; r a) -&gt; <a>Prod</a> '[f, g, h] a
--           ⋮
--   </pre>
uncurryn :: Curried (Prod fs a -> r a) -> Prod fs a -> r a

-- | Type-level, poly-kinded, list-concatenation.
type family (++) l r :: [k]

-- | <tt><a>Prod</a> '[f, g, h] a -&gt; r</tt> is the type of the uncurried
--   form of a function <tt>f a -&gt; g a -&gt; h a -&gt; r</tt>.
--   <a>Curried</a> moves from the former to the later. E.g.
--   
--   <pre>
--   <a>Curried</a> (<a>Prod</a> '[]  a    -&gt; r) = r a
--   <a>Curried</a> (<a>Prod</a> '[f] a    -&gt; r) = f a -&gt; r a
--   <a>Curried</a> (<a>Prod</a> '[f, g] a -&gt; r) = f a -&gt; g a -&gt; r a
--   </pre>
type family Curried t
instance GHC.Base.Functor (Data.Functor.Prod.Prod '[])
instance (GHC.Base.Functor f, GHC.Base.Functor (Data.Functor.Prod.Prod fs)) => GHC.Base.Functor (Data.Functor.Prod.Prod (f : fs))
instance GHC.Base.Applicative (Data.Functor.Prod.Prod '[])
instance (GHC.Base.Applicative f, GHC.Base.Applicative (Data.Functor.Prod.Prod fs)) => GHC.Base.Applicative (Data.Functor.Prod.Prod (f : fs))
instance GHC.Base.Alternative (Data.Functor.Prod.Prod '[])
instance (GHC.Base.Alternative f, GHC.Base.Alternative (Data.Functor.Prod.Prod fs)) => GHC.Base.Alternative (Data.Functor.Prod.Prod (f : fs))
instance Data.Foldable.Foldable (Data.Functor.Prod.Prod '[])
instance (Data.Foldable.Foldable f, Data.Foldable.Foldable (Data.Functor.Prod.Prod fs)) => Data.Foldable.Foldable (Data.Functor.Prod.Prod (f : fs))
instance Data.Traversable.Traversable (Data.Functor.Prod.Prod '[])
instance (Data.Traversable.Traversable f, Data.Traversable.Traversable (Data.Functor.Prod.Prod fs)) => Data.Traversable.Traversable (Data.Functor.Prod.Prod (f : fs))
instance Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod '[])
instance (Data.Functor.Classes.Eq1 f, Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod fs)) => Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod (f : fs))
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Functor.Prod.Prod '[] a)
instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq a, Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod fs)) => GHC.Classes.Eq (Data.Functor.Prod.Prod (f : fs) a)
instance Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod '[])
instance (Data.Functor.Classes.Ord1 f, Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod fs)) => Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod (f : fs))
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Functor.Prod.Prod '[] a)
instance (Data.Functor.Classes.Ord1 f, GHC.Classes.Ord a, Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod fs)) => GHC.Classes.Ord (Data.Functor.Prod.Prod (f : fs) a)
instance Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod '[])
instance (Data.Functor.Classes.Show1 f, Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod fs)) => Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod (f : fs))
instance GHC.Show.Show a => GHC.Show.Show (Data.Functor.Prod.Prod '[] a)
instance (Data.Functor.Classes.Show1 f, GHC.Show.Show a, Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod fs)) => GHC.Show.Show (Data.Functor.Prod.Prod (f : fs) a)


-- | Sometimes one needs a type like <tt>Barbie <a>Identity</a></tt> and it
--   may feel like a second-class record type, where one needs to unpack
--   values in each field. For those cases, we can leverage on closed
--   type-families:
--   
--   <pre>
--   data <a>Bare</a>
--   data <a>Covered</a>
--   
--   type family <a>Wear</a> t f a where
--     <a>Wear</a> <a>Bare</a>    f a = a
--     <a>Wear</a> <a>Covered</a> f a = f a
--   
--   data SignUpForm t f
--     = SignUpForm
--         { username  :: <a>Wear</a> t f <a>String</a>,
--         , password  :: <a>Wear</a> t f <a>String</a>
--         , mailingOk :: <a>Wear</a> t f <a>Bool</a>
--         }
--    instance <a>FunctorB</a> (SignUpForm <a>Covered</a>)
--    instance <a>TraversableB</a> (SignUpForm <a>Covered</a>)
--    ...,
--    instance <a>BareB</a> SignUpForm
--   
--   type SignUpRaw  = SignUpForm <a>Covered</a> <a>Maybe</a>
--   type SignUpData = SignUpForm <a>Bare</a> <tt>Identity</tt>
--   
--   formData = SignUpForm "jbond" "shaken007" False :: SignUpData
--   </pre>
module Barbies.Bare

-- | The <a>Wear</a> type-function allows one to define a Barbie-type as
--   
--   <pre>
--   data B t f
--     = B { f1 :: <a>Wear</a> t f <a>Int</a>
--         , f2 :: <a>Wear</a> t f <a>Bool</a>
--         }
--   </pre>
--   
--   This gives rise to two rather different types:
--   
--   <ul>
--   <li><tt>B <a>Covered</a> f</tt> is a normal Barbie-type, in the sense
--   that <tt>f1 :: B <a>Covered</a> f -&gt; f <a>Int</a></tt>, etc.</li>
--   <li><tt>B <a>Bare</a> f</tt>, on the other hand, is a normal record
--   with no functor around the type:</li>
--   </ul>
--   
--   <pre>
--   B { f1 :: 5, f2 = <a>True</a> } :: B <a>Bare</a> f
--   </pre>
type family Wear t f a
data Bare
data Covered

-- | Class of Barbie-types defined using <a>Wear</a> and can therefore have
--   <a>Bare</a> versions. Must satisfy:
--   
--   <pre>
--   <a>bcover</a> . <a>bstrip</a> = <a>id</a>
--   <a>bstrip</a> . <a>bcover</a> = <a>id</a>
--   </pre>
class FunctorB (b Covered) => BareB b
bstrip :: BareB b => b Covered Identity -> b Bare Identity
bcover :: BareB b => b Bare Identity -> b Covered Identity
bstrip :: (BareB b, CanDeriveBareB b) => b Covered Identity -> b Bare Identity
bcover :: (BareB b, CanDeriveBareB b) => b Bare Identity -> b Covered Identity

-- | Generalization of <a>bstrip</a> to arbitrary functors
bstripFrom :: BareB b => (forall a. f a -> a) -> b Covered f -> b Bare Identity

-- | Generalization of <a>bcover</a> to arbitrary functors
bcoverWith :: BareB b => (forall a. a -> f a) -> b Bare Identity -> b Covered f

-- | Like the <a>Wear</a> family, but with two wrappers <tt>f</tt> and
--   <tt>g</tt> instead of one. This is useful if you have a data-type
--   where <tt>f</tt> is parametric but <tt>g</tt> is not, consider this:
--   
--   <pre>
--   data T t f =
--     T { f1 :: <a>Wear</a>    t f [Bool]
--       , f2 :: <a>Wear</a>    t f (Sum Int)
--       , f3 :: <a>WearTwo</a> t f Sum Int
--       , f4 :: <a>WearTwo</a> t f Max Int
--       }
--   </pre>
--   
--   with <tt>x :: T Covered Option</tt> we would have
--   
--   <pre>
--   f1 x :: IO (Option [Bool])
--   f2 x :: IO (Option (Sum Int))
--   f3 x :: IO (Option (Sum Int))
--   f4 x :: IO (Option (Max Int))
--   </pre>
--   
--   and with <tt>y :: T Bare Identity</tt> we would have
--   
--   <pre>
--   f1 y :: Int
--   f2 y :: Sum Int
--   f3 y :: Int
--   f4 y :: Int
--   </pre>
--   
--   Note how <tt>(Option (Sum Int))</tt> (or <tt>Max</tt>) has a nice
--   Semigroup instance that we can use to merge two (covered) barbies,
--   while <a>WearTwo</a> removes the wrapper for the bare barbie.
type family WearTwo t f g a


-- | <i>Deprecated: Use Barbies.Bare</i>
module Data.Barbie.Bare

-- | The <a>Wear</a> type-function allows one to define a Barbie-type as
--   
--   <pre>
--   data B t f
--     = B { f1 :: <a>Wear</a> t f <a>Int</a>
--         , f2 :: <a>Wear</a> t f <a>Bool</a>
--         }
--   </pre>
--   
--   This gives rise to two rather different types:
--   
--   <ul>
--   <li><tt>B <a>Covered</a> f</tt> is a normal Barbie-type, in the sense
--   that <tt>f1 :: B <a>Covered</a> f -&gt; f <a>Int</a></tt>, etc.</li>
--   <li><tt>B <a>Bare</a> f</tt>, on the other hand, is a normal record
--   with no functor around the type:</li>
--   </ul>
--   
--   <pre>
--   B { f1 :: 5, f2 = <a>True</a> } :: B <a>Bare</a> f
--   </pre>
type family Wear t f a
data Bare
data Covered

-- | Class of Barbie-types defined using <a>Wear</a> and can therefore have
--   <a>Bare</a> versions. Must satisfy:
--   
--   <pre>
--   <a>bcover</a> . <a>bstrip</a> = <a>id</a>
--   <a>bstrip</a> . <a>bcover</a> = <a>id</a>
--   </pre>
class FunctorB (b Covered) => BareB b
bstrip :: BareB b => b Covered Identity -> b Bare Identity
bcover :: BareB b => b Bare Identity -> b Covered Identity
bstrip :: (BareB b, CanDeriveBareB b) => b Covered Identity -> b Bare Identity
bcover :: (BareB b, CanDeriveBareB b) => b Bare Identity -> b Covered Identity

-- | Generalization of <a>bstrip</a> to arbitrary functors
bstripFrom :: BareB b => (forall a. f a -> a) -> b Covered f -> b Bare Identity

-- | Generalization of <a>bcover</a> to arbitrary functors
bcoverWith :: BareB b => (forall a. a -> f a) -> b Bare Identity -> b Covered f


-- | Functors on indexed-types.
module Data.Functor.Transformer

-- | Functor from indexed-types to indexed-types. Instances of
--   <a>FunctorT</a> should satisfy the following laws:
--   
--   <pre>
--   <a>tmap</a> <a>id</a> = <a>id</a>
--   <a>tmap</a> f . <a>tmap</a> g = <a>tmap</a> (f . g)
--   </pre>
--   
--   There is a default <a>tmap</a> implementation for <a>Generic</a>
--   types, so instances can derived automatically.
class FunctorT (t :: (k -> Type) -> k' -> Type)
tmap :: FunctorT t => (forall a. f a -> g a) -> t f x -> t g x
tmap :: forall f g x. (FunctorT t, CanDeriveFunctorT t f g x) => (forall a. f a -> g a) -> t f x -> t g x

-- | Indexed-functors that can be traversed from left to right. Instances
--   should satisfy the following laws:
--   
--   <pre>
--    t . <a>ttraverse</a> f   = <a>ttraverse</a> (t . f)  -- naturality
--   <a>ttraverse</a> <a>Identity</a> = <a>Identity</a>           -- identity
--   <a>ttraverse</a> (<a>Compose</a> . <a>fmap</a> g . f) = <a>Compose</a> . <a>fmap</a> (<a>ttraverse</a> g) . <a>ttraverse</a> f -- composition
--   </pre>
--   
--   There is a default <a>ttraverse</a> implementation for <a>Generic</a>
--   types, so instances can derived automatically.
class FunctorT t => TraversableT (t :: (k -> Type) -> k' -> Type)
ttraverse :: (TraversableT t, Applicative e) => (forall a. f a -> e (g a)) -> t f x -> e (t g x)
ttraverse :: (TraversableT t, Applicative e, CanDeriveTraversableT t f g x) => (forall a. f a -> e (g a)) -> t f x -> e (t g x)

-- | Map each element to an action, evaluate these actions from left to
--   right, and ignore the results.
ttraverse_ :: (TraversableT t, Applicative e) => (forall a. f a -> e c) -> t f x -> e ()

-- | Map each element to a monoid, and combine the results.
tfoldMap :: (TraversableT t, Monoid m) => (forall a. f a -> m) -> t f x -> m

-- | Evaluate each action in the structure from left to right, and collect
--   the results.
tsequence :: (Applicative e, TraversableT t) => t (Compose e f) x -> e (t f x)

-- | A version of <a>tsequence</a> with <tt>f</tt> specialized to
--   <a>Identity</a>.
tsequence' :: (Applicative e, TraversableT t) => t e x -> e (t Identity x)

-- | A <a>FunctorT</a> where the effects can be distributed to the fields:
--   <a>tdistribute</a> turns an effectful way of building a
--   transformer-type into a pure transformer-type with effectful ways of
--   computing the values of its fields.
--   
--   This class is the categorical dual of <a>TraversableT</a>, with
--   <a>tdistribute</a> the dual of <a>tsequence</a> and <a>tcotraverse</a>
--   the dual of <a>ttraverse</a>. As such, instances need to satisfy these
--   laws:
--   
--   <pre>
--   <a>tdistribute</a> . h = <a>tmap</a> (<a>Compose</a> . h . <a>getCompose</a>) . <a>tdistribute</a>    -- naturality
--   <a>tdistribute</a> . <a>Identity</a> = <a>tmap</a> (<a>Compose</a> . <a>Identity</a>)                 -- identity
--   <a>tdistribute</a> . <a>Compose</a> = <a>fmap</a> (<a>Compose</a> . <a>Compose</a> . <a>fmap</a> <a>getCompose</a> . <a>getCompose</a>) . <a>tdistribute</a> . <a>fmap</a> <a>distribute</a> -- composition
--   </pre>
--   
--   By specializing <tt>f</tt> to <tt>((-&gt;) a)</tt> and <tt>g</tt> to
--   <a>Identity</a>, we can define a function that decomposes a function
--   on distributive transformers into a collection of simpler functions:
--   
--   <pre>
--   <a>tdecompose</a> :: <a>DistributiveT</a> b =&gt; (a -&gt; b <a>Identity</a>) -&gt; b ((-&gt;) a)
--   <a>tdecompose</a> = <a>tmap</a> (<a>fmap</a> <a>runIdentity</a> . <a>getCompose</a>) . <a>tdistribute</a>
--   </pre>
--   
--   Lawful instances of the class can then be characterized as those that
--   satisfy:
--   
--   <pre>
--   <a>trecompose</a> . <a>tdecompose</a> = <a>id</a>
--   <a>tdecompose</a> . <a>trecompose</a> = <a>id</a>
--   </pre>
--   
--   This means intuitively that instances need to have a fixed shape (i.e.
--   no sum-types can be involved). Typically, this means record types, as
--   long as they don't contain fields where the functor argument is not
--   applied.
--   
--   There is a default implementation of <a>tdistribute</a> based on
--   <a>Generic</a>. Intuitively, it works on product types where the shape
--   of a pure value is uniquely defined and every field is covered by the
--   argument <tt>f</tt>.
class FunctorT t => DistributiveT (t :: (Type -> Type) -> i -> Type)
tdistribute :: (DistributiveT t, Functor f) => f (t g x) -> t (Compose f g) x
tdistribute :: forall f g x. (DistributiveT t, CanDeriveDistributiveT t f g x) => f (t g x) -> t (Compose f g) x

-- | A version of <a>tdistribute</a> with <tt>g</tt> specialized to
--   <a>Identity</a>.
tdistribute' :: (DistributiveT t, Functor f) => f (t Identity x) -> t f x

-- | Dual of <a>ttraverse</a>
tcotraverse :: (DistributiveT t, Functor f) => (forall a. f (g a) -> f a) -> f (t g x) -> t f x

-- | Decompose a function returning a distributive transformer, into a
--   collection of simpler functions.
tdecompose :: DistributiveT t => (a -> t Identity x) -> t ((->) a) x

-- | Recompose a decomposed function.
trecompose :: FunctorT t => t ((->) a) x -> a -> t Identity x

-- | A <a>FunctorT</a> with application, providing operations to:
--   
--   <ul>
--   <li>embed an "empty" value (<a>tpure</a>)</li>
--   <li>align and combine values (<a>tprod</a>)</li>
--   </ul>
--   
--   It should satisfy the following laws:
--   
--   <ul>
--   <li><i>Naturality of <a>tprod</a></i></li>
--   </ul>
--   
--   <pre>
--   <a>tmap</a> ((<a>Pair</a> a b) -&gt; <a>Pair</a> (f a) (g b)) (u `<tt>tprod'</tt> v) = <a>tmap</a> f u `<tt>tprod'</tt> <a>tmap</a> g v
--   </pre>
--   
--   <ul>
--   <li><i>Left and right identity</i></li>
--   </ul>
--   
--   <pre>
--   <a>tmap</a> ((<a>Pair</a> _ b) -&gt; b) (<a>tpure</a> e `<tt>tprod'</tt> v) = v
--   <a>tmap</a> ((<a>Pair</a> a _) -&gt; a) (u `<tt>tprod'</tt> <a>tpure</a> e) = u
--   </pre>
--   
--   <ul>
--   <li><i>Associativity</i></li>
--   </ul>
--   
--   <pre>
--   <a>tmap</a> ((<a>Pair</a> a (<a>Pair</a> b c)) -&gt; <a>Pair</a> (<a>Pair</a> a b) c) (u `<tt>tprod'</tt> (v `<tt>tprod'</tt> w)) = (u `<tt>tprod'</tt> v) `<tt>tprod'</tt> w
--   </pre>
--   
--   It is to <a>FunctorT</a> in the same way is <a>Applicative</a> relates
--   to <a>Functor</a>. For a presentation of <a>Applicative</a> as a
--   monoidal functor, see Section 7 of <a>Applicative Programming with
--   Effects</a>.
--   
--   There is a default implementation of <a>tprod</a> and <a>tpure</a>
--   based on <a>Generic</a>. Intuitively, it works on types where the
--   value of <a>tpure</a> is uniquely defined. This corresponds rougly to
--   record types (in the presence of sums, there would be several
--   candidates for <a>tpure</a>), where every field is either a
--   <a>Monoid</a> or covered by the argument <tt>f</tt>.
class FunctorT t => ApplicativeT (t :: (k -> Type) -> (k' -> Type))
tpure :: ApplicativeT t => (forall a. f a) -> t f x
tprod :: ApplicativeT t => t f x -> t g x -> t (f `Product` g) x
tpure :: (ApplicativeT t, CanDeriveApplicativeT t f f x) => (forall a. f a) -> t f x
tprod :: (ApplicativeT t, CanDeriveApplicativeT t f g x) => t f x -> t g x -> t (f `Product` g) x

-- | An alias of <a>tprod</a>.
tzip :: ApplicativeT t => t f x -> t g x -> t (f `Product` g) x

-- | An equivalent of <a>unzip</a>.
tunzip :: ApplicativeT t => t (f `Product` g) x -> (t f x, t g x)

-- | An equivalent of <a>zipWith</a>.
tzipWith :: ApplicativeT t => (forall a. f a -> g a -> h a) -> t f x -> t g x -> t h x

-- | An equivalent of <a>zipWith3</a>.
tzipWith3 :: ApplicativeT t => (forall a. f a -> g a -> h a -> i a) -> t f x -> t g x -> t h x -> t i x

-- | An equivalent of <a>zipWith4</a>.
tzipWith4 :: ApplicativeT t => (forall a. f a -> g a -> h a -> i a -> j a) -> t f x -> t g x -> t h x -> t i x -> t j x

-- | Some endo-functors on indexed-types are monads. Common examples would
--   be "functor-transformers", like <a>Compose</a> or <a>ReaderT</a>. In
--   that sense, <a>MonadT</a> is similar to <a>MonadTrans</a> but with
--   additional structure (see also <a>mmorph</a>'s <tt>MMonad</tt> class).
--   
--   Notice though that while <a>lift</a> assumes a <a>Monad</a> instance
--   of the value to be lifted, <a>tlift</a> has no such constraint. This
--   means we cannot have instances for most "monad transformers", since
--   lifting typically involves an <a>fmap</a>.
--   
--   <a>MonadT</a> also corresponds to the indexed-monad of <a>Kleisli
--   arrows of outrageous fortune</a>.
--   
--   Instances of this class should to satisfy the monad laws. They laws
--   can stated either in terms of <tt>(<a>tlift</a>, <a>tjoin</a>)</tt> or
--   <tt>(<a>tlift</a>, <a>tembed</a>)</tt>. In the former:
--   
--   <pre>
--   <a>tmap</a> h . <a>tlift</a> = <a>tlift</a> . h
--   <a>tmap</a> h . <a>tjoin</a> = <a>tjoin</a> . <a>tmap</a> (<a>tmap</a> h)
--   <a>tjoin</a> . <a>tlift</a>  = <a>id</a>
--   <a>tjoin</a> . 'tmap tlift' = <a>id</a>
--   <a>tjoin</a> . <a>tjoin</a> = <a>tjoin</a> . <a>tmap</a> <a>tjoin</a>
--   </pre>
--   
--   In the latter:
--   
--   <pre>
--   <a>tembed</a> f . <a>tlift</a> = f
--   <a>tembed</a> <a>tlift</a> = <a>id</a>
--   <a>tembed</a> f . <a>tembed</a> g = <a>tembed</a> (<a>tembed</a> f . g)
--   </pre>
class FunctorT t => MonadT t

-- | Lift a functor to a transformed functor.
tlift :: MonadT t => f a -> t f a

-- | The conventional monad join operator. It is used to remove one level
--   of monadic structure, projecting its bound argument into the outer
--   level.
tjoin :: MonadT t => t (t f) a -> t f a

-- | Analogous to <tt>(<a>=&lt;&lt;</a>)</tt>.
tembed :: (MonadT t, MonadT t) => (forall x. f x -> t g x) -> t f a -> t g a

-- | Instances of this class provide means to talk about constraints, both
--   at compile-time, using <a>AllT</a>, and at run-time, in the form of
--   <a>Dict</a>, via <a>taddDicts</a>.
--   
--   A manual definition would look like this:
--   
--   <pre>
--   data T f a = A (f <a>Int</a>) (f <a>String</a>) | B (f <a>Bool</a>) (f <a>Int</a>)
--   
--   instance <a>ConstraintsT</a> T where
--     type <a>AllT</a> c T = (c <a>Int</a>, c <a>String</a>, c <a>Bool</a>)
--   
--     <a>taddDicts</a> t = case t of
--       A x y -&gt; A (<a>Pair</a> <a>Dict</a> x) (<a>Pair</a> <a>Dict</a> y)
--       B z w -&gt; B (<a>Pair</a> <a>Dict</a> z) (<a>Pair</a> <a>Dict</a> w)
--   </pre>
--   
--   Now, when we given a <tt>T f</tt>, if we need to use the <a>Show</a>
--   instance of their fields, we can use:
--   
--   <pre>
--   <a>taddDicts</a> :: AllT Show t =&gt; t f -&gt; t (<a>Dict</a> <a>Show</a> `<tt>Product'</tt> f)
--   </pre>
--   
--   There is a default implementation of <a>ConstraintsT</a> for
--   <a>Generic</a> types, so in practice one will simply do:
--   
--   <pre>
--   derive instance <a>Generic</a> (T f a)
--   instance <a>ConstraintsT</a> T
--   </pre>
class FunctorT t => ConstraintsT (t :: (kl -> Type) -> (kr -> Type)) where {
    
    -- | <tt><a>AllT</a> c t</tt> should contain a constraint <tt>c a</tt> for
    --   each <tt>a</tt> occurring under an <tt>f</tt> in <tt>t f</tt>.
    --   
    --   For requiring constraints of the form <tt>c (f a)</tt>, use
    --   <a>AllTF</a>.
    type AllT (c :: k -> Constraint) t :: Constraint;
    type AllT c t = GAll 1 c (GAllRepT t);
}
taddDicts :: forall c f x. (ConstraintsT t, AllT c t) => t f x -> t (Dict c `Product` f) x
taddDicts :: forall c f x. (ConstraintsT t, CanDeriveConstraintsT c t f x, AllT c t) => t f x -> t (Dict c `Product` f) x

-- | Similar to <a>AllT</a> but will put the functor argument <tt>f</tt>
--   between the constraint <tt>c</tt> and the type <tt>a</tt>.
type AllTF c f t = AllT (ClassF c f) t

-- | Like <a>tmap</a> but a constraint is allowed to be required on each
--   element of <tt>t</tt>.
tmapC :: forall c t f g x. (AllT c t, ConstraintsT t) => (forall a. c a => f a -> g a) -> t f x -> t g x

-- | Like <a>ttraverse</a> but with a constraint on the elements of
--   <tt>t</tt>.
ttraverseC :: forall c t f g e x. (TraversableT t, ConstraintsT t, AllT c t, Applicative e) => (forall a. c a => f a -> e (g a)) -> t f x -> e (t g x)
newtype Rec (p :: Type) a x
Rec :: K1 R a x -> Rec (p :: Type) a x
[unRec] :: Rec (p :: Type) a x -> K1 R a x


-- | Functors from indexed-types to types.
module Data.Functor.Barbie

-- | Barbie-types that can be mapped over. Instances of <a>FunctorB</a>
--   should satisfy the following laws:
--   
--   <pre>
--   <a>bmap</a> <a>id</a> = <a>id</a>
--   <a>bmap</a> f . <a>bmap</a> g = <a>bmap</a> (f . g)
--   </pre>
--   
--   There is a default <a>bmap</a> implementation for <a>Generic</a>
--   types, so instances can derived automatically.
class FunctorB (b :: (k -> Type) -> Type)
bmap :: FunctorB b => (forall a. f a -> g a) -> b f -> b g
bmap :: forall f g. (FunctorB b, CanDeriveFunctorB b f g) => (forall a. f a -> g a) -> b f -> b g

-- | Barbie-types that can be traversed from left to right. Instances
--   should satisfy the following laws:
--   
--   <pre>
--    t . <a>btraverse</a> f   = <a>btraverse</a> (t . f)  -- naturality
--   <a>btraverse</a> <a>Identity</a> = <a>Identity</a>           -- identity
--   <a>btraverse</a> (<a>Compose</a> . <a>fmap</a> g . f) = <a>Compose</a> . <a>fmap</a> (<a>btraverse</a> g) . <a>btraverse</a> f -- composition
--   </pre>
--   
--   There is a default <a>btraverse</a> implementation for <a>Generic</a>
--   types, so instances can derived automatically.
class FunctorB b => TraversableB (b :: (k -> Type) -> Type)
btraverse :: (TraversableB b, Applicative e) => (forall a. f a -> e (g a)) -> b f -> e (b g)
btraverse :: (TraversableB b, Applicative e, CanDeriveTraversableB b f g) => (forall a. f a -> e (g a)) -> b f -> e (b g)

-- | Map each element to an action, evaluate these actions from left to
--   right, and ignore the results.
btraverse_ :: (TraversableB b, Applicative e) => (forall a. f a -> e c) -> b f -> e ()

-- | Map each element to a monoid, and combine the results.
bfoldMap :: (TraversableB b, Monoid m) => (forall a. f a -> m) -> b f -> m

-- | Evaluate each action in the structure from left to right, and collect
--   the results.
bsequence :: (Applicative e, TraversableB b) => b (Compose e f) -> e (b f)

-- | A version of <a>bsequence</a> with <tt>f</tt> specialized to
--   <a>Identity</a>.
bsequence' :: (Applicative e, TraversableB b) => b e -> e (b Identity)

-- | A <a>FunctorB</a> where the effects can be distributed to the fields:
--   <a>bdistribute</a> turns an effectful way of building a Barbie-type
--   into a pure Barbie-type with effectful ways of computing the values of
--   its fields.
--   
--   This class is the categorical dual of <a>TraversableB</a>, with
--   <a>bdistribute</a> the dual of <a>bsequence</a> and <a>bcotraverse</a>
--   the dual of <a>btraverse</a>. As such, instances need to satisfy these
--   laws:
--   
--   <pre>
--   <a>bdistribute</a> . h = <a>bmap</a> (<a>Compose</a> . h . <a>getCompose</a>) . <a>bdistribute</a>    -- naturality
--   <a>bdistribute</a> . <a>Identity</a> = <a>bmap</a> (<a>Compose</a> . <a>Identity</a>)                 -- identity
--   <a>bdistribute</a> . <a>Compose</a> = <a>bmap</a> (<a>Compose</a> . <a>Compose</a> . <a>fmap</a> <a>getCompose</a> . <a>getCompose</a>) . <a>bdistribute</a> . <a>fmap</a> <a>bdistribute</a> -- composition
--   </pre>
--   
--   By specializing <tt>f</tt> to <tt>((-&gt;) a)</tt> and <tt>g</tt> to
--   <a>Identity</a>, we can define a function that decomposes a function
--   on distributive barbies into a collection of simpler functions:
--   
--   <pre>
--   <a>bdecompose</a> :: <a>DistributiveB</a> b =&gt; (a -&gt; b <a>Identity</a>) -&gt; b ((-&gt;) a)
--   <a>bdecompose</a> = <a>bmap</a> (<a>fmap</a> <a>runIdentity</a> . <a>getCompose</a>) . <a>bdistribute</a>
--   </pre>
--   
--   Lawful instances of the class can then be characterized as those that
--   satisfy:
--   
--   <pre>
--   <a>brecompose</a> . <a>bdecompose</a> = <a>id</a>
--   <a>bdecompose</a> . <a>brecompose</a> = <a>id</a>
--   </pre>
--   
--   This means intuitively that instances need to have a fixed shape (i.e.
--   no sum-types can be involved). Typically, this means record types, as
--   long as they don't contain fields where the functor argument is not
--   applied.
--   
--   There is a default implementation of <a>bdistribute</a> based on
--   <a>Generic</a>. Intuitively, it works on product types where the shape
--   of a pure value is uniquely defined and every field is covered by the
--   argument <tt>f</tt>.
class (FunctorB b) => DistributiveB (b :: (k -> Type) -> Type)
bdistribute :: (DistributiveB b, Functor f) => f (b g) -> b (Compose f g)
bdistribute :: forall f g. (DistributiveB b, CanDeriveDistributiveB b f g) => Functor f => f (b g) -> b (Compose f g)

-- | A version of <a>bdistribute</a> with <tt>g</tt> specialized to
--   <a>Identity</a>.
bdistribute' :: (DistributiveB b, Functor f) => f (b Identity) -> b f

-- | Dual of <a>btraverse</a>
bcotraverse :: (DistributiveB b, Functor f) => (forall a. f (g a) -> f a) -> f (b g) -> b f

-- | Decompose a function returning a distributive barbie, into a
--   collection of simpler functions.
bdecompose :: DistributiveB b => (a -> b Identity) -> b ((->) a)

-- | Recompose a decomposed function.
brecompose :: FunctorB b => b ((->) a) -> a -> b Identity

-- | A <a>FunctorB</a> with application, providing operations to:
--   
--   <ul>
--   <li>embed an "empty" value (<a>bpure</a>)</li>
--   <li>align and combine values (<a>bprod</a>)</li>
--   </ul>
--   
--   It should satisfy the following laws:
--   
--   <ul>
--   <li><i>Naturality of <a>bprod</a></i></li>
--   </ul>
--   
--   <pre>
--   <a>bmap</a> ((<a>Pair</a> a b) -&gt; <a>Pair</a> (f a) (g b)) (u `<tt>bprod'</tt> v) = <a>bmap</a> f u `<tt>bprod'</tt> <a>bmap</a> g v
--   </pre>
--   
--   <ul>
--   <li><i>Left and right identity</i></li>
--   </ul>
--   
--   <pre>
--   <a>bmap</a> ((<a>Pair</a> _ b) -&gt; b) (<a>bpure</a> e `<tt>bprod'</tt> v) = v
--   <a>bmap</a> ((<a>Pair</a> a _) -&gt; a) (u `<tt>bprod'</tt> <a>bpure</a> e) = u
--   </pre>
--   
--   <ul>
--   <li><i>Associativity</i></li>
--   </ul>
--   
--   <pre>
--   <a>bmap</a> ((<a>Pair</a> a (<a>Pair</a> b c)) -&gt; <a>Pair</a> (<a>Pair</a> a b) c) (u `<tt>bprod'</tt> (v `<tt>bprod'</tt> w)) = (u `<tt>bprod'</tt> v) `<tt>bprod'</tt> w
--   </pre>
--   
--   It is to <a>FunctorB</a> in the same way as <a>Applicative</a> relates
--   to <a>Functor</a>. For a presentation of <a>Applicative</a> as a
--   monoidal functor, see Section 7 of <a>Applicative Programming with
--   Effects</a>.
--   
--   There is a default implementation of <a>bprod</a> and <a>bpure</a>
--   based on <a>Generic</a>. Intuitively, it works on types where the
--   value of <a>bpure</a> is uniquely defined. This corresponds rougly to
--   record types (in the presence of sums, there would be several
--   candidates for <a>bpure</a>), where every field is either a
--   <a>Monoid</a> or covered by the argument <tt>f</tt>.
class FunctorB b => ApplicativeB (b :: (k -> Type) -> Type)
bpure :: ApplicativeB b => (forall a. f a) -> b f
bprod :: ApplicativeB b => b f -> b g -> b (f `Product` g)
bpure :: (ApplicativeB b, CanDeriveApplicativeB b f f) => (forall a. f a) -> b f
bprod :: (ApplicativeB b, CanDeriveApplicativeB b f g) => b f -> b g -> b (f `Product` g)

-- | An alias of <a>bprod</a>, since this is like a <a>zip</a>.
bzip :: ApplicativeB b => b f -> b g -> b (f `Product` g)

-- | An equivalent of <a>unzip</a>.
bunzip :: ApplicativeB b => b (f `Product` g) -> (b f, b g)

-- | An equivalent of <a>zipWith</a>.
bzipWith :: ApplicativeB b => (forall a. f a -> g a -> h a) -> b f -> b g -> b h

-- | An equivalent of <a>zipWith3</a>.
bzipWith3 :: ApplicativeB b => (forall a. f a -> g a -> h a -> i a) -> b f -> b g -> b h -> b i

-- | An equivalent of <a>zipWith4</a>.
bzipWith4 :: ApplicativeB b => (forall a. f a -> g a -> h a -> i a -> j a) -> b f -> b g -> b h -> b i -> b j

-- | Instances of this class provide means to talk about constraints, both
--   at compile-time, using <a>AllB</a>, and at run-time, in the form of
--   <a>Dict</a>, via <a>baddDicts</a>.
--   
--   A manual definition would look like this:
--   
--   <pre>
--   data T f = A (f <a>Int</a>) (f <a>String</a>) | B (f <a>Bool</a>) (f <a>Int</a>)
--   
--   instance <a>ConstraintsB</a> T where
--     type <a>AllB</a> c T = (c <a>Int</a>, c <a>String</a>, c <a>Bool</a>)
--   
--     <a>baddDicts</a> t = case t of
--       A x y -&gt; A (<a>Pair</a> <a>Dict</a> x) (<a>Pair</a> <a>Dict</a> y)
--       B z w -&gt; B (<a>Pair</a> <a>Dict</a> z) (<a>Pair</a> <a>Dict</a> w)
--   </pre>
--   
--   Now, when we given a <tt>T f</tt>, if we need to use the <a>Show</a>
--   instance of their fields, we can use:
--   
--   <pre>
--   <a>baddDicts</a> :: AllB Show b =&gt; b f -&gt; b (<a>Dict</a> <a>Show</a> `<tt>Product'</tt> f)
--   </pre>
--   
--   There is a default implementation of <a>ConstraintsB</a> for
--   <a>Generic</a> types, so in practice one will simply do:
--   
--   <pre>
--   derive instance <a>Generic</a> (T f)
--   instance <a>ConstraintsB</a> T
--   </pre>
class FunctorB b => ConstraintsB (b :: (k -> Type) -> Type) where {
    
    -- | <tt><a>AllB</a> c b</tt> should contain a constraint <tt>c a</tt> for
    --   each <tt>a</tt> occurring under an <tt>f</tt> in <tt>b f</tt>. E.g.:
    --   
    --   <pre>
    --   <a>AllB</a> <a>Show</a> Person ~ (<a>Show</a> <a>String</a>, <a>Show</a> <a>Int</a>)
    --   </pre>
    --   
    --   For requiring constraints of the form <tt>c (f a)</tt>, use
    --   <a>AllBF</a>.
    type AllB (c :: k -> Constraint) b :: Constraint;
    type AllB c b = GAll 0 c (GAllRepB b);
}
baddDicts :: forall c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f)
baddDicts :: forall c f. (ConstraintsB b, CanDeriveConstraintsB c b f, AllB c b) => b f -> b (Dict c `Product` f)

-- | Similar to <a>AllB</a> but will put the functor argument <tt>f</tt>
--   between the constraint <tt>c</tt> and the type <tt>a</tt>. For
--   example:
--   
--   <pre>
--   <a>AllB</a>  <a>Show</a>   Person ~ (<a>Show</a>    <a>String</a>,  <a>Show</a>    <a>Int</a>)
--   <a>AllBF</a> <a>Show</a> f Person ~ (<a>Show</a> (f <a>String</a>), <a>Show</a> (f <a>Int</a>))
--   
--   </pre>
type AllBF c f b = AllB (ClassF c f) b

-- | Similar to <a>baddDicts</a> but can produce the instance dictionaries
--   "out of the blue".
bdicts :: forall c b. (ConstraintsB b, ApplicativeB b, AllB c b) => b (Dict c)

-- | Like <a>bmap</a> but a constraint is allowed to be required on each
--   element of <tt>b</tt>
--   
--   E.g. If all fields of <tt>b</tt> are <a>Show</a>able then you could
--   store each shown value in it's slot using <a>Const</a>:
--   
--   <pre>
--   showFields :: (AllB Show b, ConstraintsB b) =&gt; b Identity -&gt; b (Const String)
--   showFields = bmapC @Show showField
--     where
--       showField :: forall a. Show a =&gt; Identity a -&gt; Const String a
--       showField (Identity a) = Const (show a)
--   </pre>
bmapC :: forall c b f g. (AllB c b, ConstraintsB b) => (forall a. c a => f a -> g a) -> b f -> b g
bfoldMapC :: forall c b m f. (TraversableB b, ConstraintsB b, AllB c b, Monoid m) => (forall a. c a => f a -> m) -> b f -> m

-- | Like <a>btraverse</a> but with a constraint on the elements of
--   <tt>b</tt>.
btraverseC :: forall c b f g e. (TraversableB b, ConstraintsB b, AllB c b, Applicative e) => (forall a. c a => f a -> e (g a)) -> b f -> e (b g)

-- | Like <a>bpure</a> but a constraint is allowed to be required on each
--   element of <tt>b</tt>.
bpureC :: forall c f b. (AllB c b, ConstraintsB b, ApplicativeB b) => (forall a. c a => f a) -> b f

-- | Like <a>bzipWith</a> but with a constraint on the elements of
--   <tt>b</tt>.
bzipWithC :: forall c b f g h. (AllB c b, ConstraintsB b, ApplicativeB b) => (forall a. c a => f a -> g a -> h a) -> b f -> b g -> b h

-- | Like <a>bzipWith3</a> but with a constraint on the elements of
--   <tt>b</tt>.
bzipWith3C :: forall c b f g h i. (AllB c b, ConstraintsB b, ApplicativeB b) => (forall a. c a => f a -> g a -> h a -> i a) -> b f -> b g -> b h -> b i

-- | Like <a>bzipWith4</a> but with a constraint on the elements of
--   <tt>b</tt>.
bzipWith4C :: forall c b f g h i j. (AllB c b, ConstraintsB b, ApplicativeB b) => (forall a. c a => f a -> g a -> h a -> i a -> j a) -> b f -> b g -> b h -> b i -> b j

-- | Builds a <tt>b f</tt>, by applying <a>mempty</a> on every field of
--   <tt>b</tt>.
bmempty :: forall f b. (AllBF Monoid f b, ConstraintsB b, ApplicativeB b) => b f
newtype Rec (p :: Type) a x
Rec :: K1 R a x -> Rec (p :: Type) a x
[unRec] :: Rec (p :: Type) a x -> K1 R a x


-- | <i>Deprecated: Use Data.Functor.Barbie or Barbie.Constraints</i>
module Data.Barbie.Constraints

-- | <tt><a>Dict</a> c a</tt> is evidence that there exists an instance of
--   <tt>c a</tt>.
--   
--   It is essentially equivalent to <tt>Dict (c a)</tt> from the
--   <a>constraints</a> package, but because of its kind, it allows us to
--   define things like <tt><a>Dict</a> <a>Show</a></tt>.
data Dict c a
[Dict] :: c a => Dict c a

-- | Turn a constrained-function into an unconstrained one that uses the
--   packed instance dictionary instead.
requiringDict :: (c a => r) -> Dict c a -> r

-- | Instances of this class provide means to talk about constraints, both
--   at compile-time, using <a>AllB</a>, and at run-time, in the form of
--   <a>Dict</a>, via <a>baddDicts</a>.
--   
--   A manual definition would look like this:
--   
--   <pre>
--   data T f = A (f <a>Int</a>) (f <a>String</a>) | B (f <a>Bool</a>) (f <a>Int</a>)
--   
--   instance <a>ConstraintsB</a> T where
--     type <a>AllB</a> c T = (c <a>Int</a>, c <a>String</a>, c <a>Bool</a>)
--   
--     <a>baddDicts</a> t = case t of
--       A x y -&gt; A (<a>Pair</a> <a>Dict</a> x) (<a>Pair</a> <a>Dict</a> y)
--       B z w -&gt; B (<a>Pair</a> <a>Dict</a> z) (<a>Pair</a> <a>Dict</a> w)
--   </pre>
--   
--   Now, when we given a <tt>T f</tt>, if we need to use the <a>Show</a>
--   instance of their fields, we can use:
--   
--   <pre>
--   <a>baddDicts</a> :: AllB Show b =&gt; b f -&gt; b (<a>Dict</a> <a>Show</a> `<tt>Product'</tt> f)
--   </pre>
--   
--   There is a default implementation of <a>ConstraintsB</a> for
--   <a>Generic</a> types, so in practice one will simply do:
--   
--   <pre>
--   derive instance <a>Generic</a> (T f)
--   instance <a>ConstraintsB</a> T
--   </pre>
class FunctorB b => ConstraintsB (b :: (k -> Type) -> Type) where {
    
    -- | <tt><a>AllB</a> c b</tt> should contain a constraint <tt>c a</tt> for
    --   each <tt>a</tt> occurring under an <tt>f</tt> in <tt>b f</tt>. E.g.:
    --   
    --   <pre>
    --   <a>AllB</a> <a>Show</a> Person ~ (<a>Show</a> <a>String</a>, <a>Show</a> <a>Int</a>)
    --   </pre>
    --   
    --   For requiring constraints of the form <tt>c (f a)</tt>, use
    --   <a>AllBF</a>.
    type AllB (c :: k -> Constraint) b :: Constraint;
    type AllB c b = GAll 0 c (GAllRepB b);
}
baddDicts :: forall c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f)
baddDicts :: forall c f. (ConstraintsB b, CanDeriveConstraintsB c b f, AllB c b) => b f -> b (Dict c `Product` f)
class (ConstraintsB b, ProductB b) => ProductBC (b :: (k -> Type) -> Type)
bdicts :: (ProductBC b, AllB c b) => b (Dict c)
bdicts :: (ProductBC b, CanDeriveProductBC c b, AllB c b) => b (Dict c)

-- | Like <a>bmap</a> but a constraint is allowed to be required on each
--   element of <tt>b</tt>
--   
--   E.g. If all fields of <tt>b</tt> are <a>Show</a>able then you could
--   store each shown value in it's slot using <a>Const</a>:
--   
--   <pre>
--   showFields :: (AllB Show b, ConstraintsB b) =&gt; b Identity -&gt; b (Const String)
--   showFields = bmapC @Show showField
--     where
--       showField :: forall a. Show a =&gt; Identity a -&gt; Const String a
--       showField (Identity a) = Const (show a)
--   </pre>
bmapC :: forall c b f g. (AllB c b, ConstraintsB b) => (forall a. c a => f a -> g a) -> b f -> b g

-- | Like <a>btraverse</a> but with a constraint on the elements of
--   <tt>b</tt>.
btraverseC :: forall c b f g e. (TraversableB b, ConstraintsB b, AllB c b, Applicative e) => (forall a. c a => f a -> e (g a)) -> b f -> e (b g)

-- | Similar to <a>AllB</a> but will put the functor argument <tt>f</tt>
--   between the constraint <tt>c</tt> and the type <tt>a</tt>. For
--   example:
--   
--   <pre>
--   <a>AllB</a>  <a>Show</a>   Person ~ (<a>Show</a>    <a>String</a>,  <a>Show</a>    <a>Int</a>)
--   <a>AllBF</a> <a>Show</a> f Person ~ (<a>Show</a> (f <a>String</a>), <a>Show</a> (f <a>Int</a>))
--   
--   </pre>
type AllBF c f b = AllB (ClassF c f) b

-- | <a>ClassF</a> has one universal instance that makes <tt><a>ClassF</a>
--   c f a</tt> equivalent to <tt>c (f a)</tt>. However, we have
--   
--   <pre>
--   'ClassF c f :: k -&gt; <a>Constraint</a>
--   </pre>
--   
--   This is useful since it allows to define constraint-constructors like
--   <tt><a>ClassF</a> <a>Monoid</a> <a>Maybe</a></tt>
class c (f a) => ClassF c f a

-- | Like <a>ClassF</a> but for binary relations.
class c (f a) (g a) => ClassFG c f g a


-- | <i>Deprecated: Use Data.Functor.Barbie or Barbies instead</i>
module Data.Barbie

-- | Barbie-types that can be mapped over. Instances of <a>FunctorB</a>
--   should satisfy the following laws:
--   
--   <pre>
--   <a>bmap</a> <a>id</a> = <a>id</a>
--   <a>bmap</a> f . <a>bmap</a> g = <a>bmap</a> (f . g)
--   </pre>
--   
--   There is a default <a>bmap</a> implementation for <a>Generic</a>
--   types, so instances can derived automatically.
class FunctorB (b :: (k -> Type) -> Type)
bmap :: FunctorB b => (forall a. f a -> g a) -> b f -> b g
bmap :: forall f g. (FunctorB b, CanDeriveFunctorB b f g) => (forall a. f a -> g a) -> b f -> b g

-- | Barbie-types that can be traversed from left to right. Instances
--   should satisfy the following laws:
--   
--   <pre>
--    t . <a>btraverse</a> f   = <a>btraverse</a> (t . f)  -- naturality
--   <a>btraverse</a> <a>Identity</a> = <a>Identity</a>           -- identity
--   <a>btraverse</a> (<a>Compose</a> . <a>fmap</a> g . f) = <a>Compose</a> . <a>fmap</a> (<a>btraverse</a> g) . <a>btraverse</a> f -- composition
--   </pre>
--   
--   There is a default <a>btraverse</a> implementation for <a>Generic</a>
--   types, so instances can derived automatically.
class FunctorB b => TraversableB (b :: (k -> Type) -> Type)
btraverse :: (TraversableB b, Applicative e) => (forall a. f a -> e (g a)) -> b f -> e (b g)
btraverse :: (TraversableB b, Applicative e, CanDeriveTraversableB b f g) => (forall a. f a -> e (g a)) -> b f -> e (b g)

-- | Map each element to an action, evaluate these actions from left to
--   right, and ignore the results.
btraverse_ :: (TraversableB b, Applicative e) => (forall a. f a -> e c) -> b f -> e ()

-- | Map each element to a monoid, and combine the results.
bfoldMap :: (TraversableB b, Monoid m) => (forall a. f a -> m) -> b f -> m

-- | Evaluate each action in the structure from left to right, and collect
--   the results.
bsequence :: (Applicative e, TraversableB b) => b (Compose e f) -> e (b f)

-- | A version of <a>bsequence</a> with <tt>f</tt> specialized to
--   <a>Identity</a>.
bsequence' :: (Applicative e, TraversableB b) => b e -> e (b Identity)

-- | <i>Deprecated: Use ApplicativeB</i>
class ApplicativeB b => ProductB (b :: (k -> Type) -> Type)
bprod :: ProductB b => b f -> b g -> b (f `Product` g)

-- | <i>Deprecated: Use bpure</i>
buniq :: ProductB b => (forall a. f a) -> b f
bprod :: (ProductB b, CanDeriveProductB b f g) => b f -> b g -> b (f `Product` g)

-- | <i>Deprecated: Use bpure</i>
buniq :: (ProductB b, CanDeriveProductB b f f) => (forall a. f a) -> b f
type CanDeriveProductB b f g = (GenericN (b f), GenericN (b g), GenericN (b (f `Product` g)), GProductB f g (RepN (b f)) (RepN (b g)) (RepN (b (f `Product` g))))

-- | An alias of <a>bprod</a>, since this is like a <a>zip</a>.
bzip :: ApplicativeB b => b f -> b g -> b (f `Product` g)

-- | An equivalent of <a>unzip</a>.
bunzip :: ApplicativeB b => b (f `Product` g) -> (b f, b g)

-- | An equivalent of <a>zipWith</a>.
bzipWith :: ApplicativeB b => (forall a. f a -> g a -> h a) -> b f -> b g -> b h

-- | An equivalent of <a>zipWith3</a>.
bzipWith3 :: ApplicativeB b => (forall a. f a -> g a -> h a -> i a) -> b f -> b g -> b h -> b i

-- | An equivalent of <a>zipWith4</a>.
bzipWith4 :: ApplicativeB b => (forall a. f a -> g a -> h a -> i a -> j a) -> b f -> b g -> b h -> b i -> b j

-- | Instances of this class provide means to talk about constraints, both
--   at compile-time, using <a>AllB</a>, and at run-time, in the form of
--   <a>Dict</a>, via <a>baddDicts</a>.
--   
--   A manual definition would look like this:
--   
--   <pre>
--   data T f = A (f <a>Int</a>) (f <a>String</a>) | B (f <a>Bool</a>) (f <a>Int</a>)
--   
--   instance <a>ConstraintsB</a> T where
--     type <a>AllB</a> c T = (c <a>Int</a>, c <a>String</a>, c <a>Bool</a>)
--   
--     <a>baddDicts</a> t = case t of
--       A x y -&gt; A (<a>Pair</a> <a>Dict</a> x) (<a>Pair</a> <a>Dict</a> y)
--       B z w -&gt; B (<a>Pair</a> <a>Dict</a> z) (<a>Pair</a> <a>Dict</a> w)
--   </pre>
--   
--   Now, when we given a <tt>T f</tt>, if we need to use the <a>Show</a>
--   instance of their fields, we can use:
--   
--   <pre>
--   <a>baddDicts</a> :: AllB Show b =&gt; b f -&gt; b (<a>Dict</a> <a>Show</a> `<tt>Product'</tt> f)
--   </pre>
--   
--   There is a default implementation of <a>ConstraintsB</a> for
--   <a>Generic</a> types, so in practice one will simply do:
--   
--   <pre>
--   derive instance <a>Generic</a> (T f)
--   instance <a>ConstraintsB</a> T
--   </pre>
class FunctorB b => ConstraintsB (b :: (k -> Type) -> Type) where {
    
    -- | <tt><a>AllB</a> c b</tt> should contain a constraint <tt>c a</tt> for
    --   each <tt>a</tt> occurring under an <tt>f</tt> in <tt>b f</tt>. E.g.:
    --   
    --   <pre>
    --   <a>AllB</a> <a>Show</a> Person ~ (<a>Show</a> <a>String</a>, <a>Show</a> <a>Int</a>)
    --   </pre>
    --   
    --   For requiring constraints of the form <tt>c (f a)</tt>, use
    --   <a>AllBF</a>.
    type AllB (c :: k -> Constraint) b :: Constraint;
    type AllB c b = GAll 0 c (GAllRepB b);
}
baddDicts :: forall c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f)
baddDicts :: forall c f. (ConstraintsB b, CanDeriveConstraintsB c b f, AllB c b) => b f -> b (Dict c `Product` f)

-- | Similar to <a>AllB</a> but will put the functor argument <tt>f</tt>
--   between the constraint <tt>c</tt> and the type <tt>a</tt>. For
--   example:
--   
--   <pre>
--   <a>AllB</a>  <a>Show</a>   Person ~ (<a>Show</a>    <a>String</a>,  <a>Show</a>    <a>Int</a>)
--   <a>AllBF</a> <a>Show</a> f Person ~ (<a>Show</a> (f <a>String</a>), <a>Show</a> (f <a>Int</a>))
--   
--   </pre>
type AllBF c f b = AllB (ClassF c f) b

-- | Like <a>bmap</a> but a constraint is allowed to be required on each
--   element of <tt>b</tt>
--   
--   E.g. If all fields of <tt>b</tt> are <a>Show</a>able then you could
--   store each shown value in it's slot using <a>Const</a>:
--   
--   <pre>
--   showFields :: (AllB Show b, ConstraintsB b) =&gt; b Identity -&gt; b (Const String)
--   showFields = bmapC @Show showField
--     where
--       showField :: forall a. Show a =&gt; Identity a -&gt; Const String a
--       showField (Identity a) = Const (show a)
--   </pre>
bmapC :: forall c b f g. (AllB c b, ConstraintsB b) => (forall a. c a => f a -> g a) -> b f -> b g

-- | Like <a>btraverse</a> but with a constraint on the elements of
--   <tt>b</tt>.
btraverseC :: forall c b f g e. (TraversableB b, ConstraintsB b, AllB c b, Applicative e) => (forall a. c a => f a -> e (g a)) -> b f -> e (b g)
class (ConstraintsB b, ProductB b) => ProductBC (b :: (k -> Type) -> Type)
bdicts :: (ProductBC b, AllB c b) => b (Dict c)
bdicts :: (ProductBC b, CanDeriveProductBC c b, AllB c b) => b (Dict c)
type CanDeriveProductBC c b = (GenericN (b (Dict c)), AllB c b ~ GAll 0 c (GAllRepB b), GProductBC c (GAllRepB b) (RepN (b (Dict c))))

-- | <i>Deprecated: Use bpureC instead</i>
buniqC :: forall c f b. (AllB c b, ProductBC b) => (forall a. c a => f a) -> b f

-- | Builds a <tt>b f</tt>, by applying <a>mempty</a> on every field of
--   <tt>b</tt>.
bmempty :: forall f b. (AllBF Monoid f b, ConstraintsB b, ApplicativeB b) => b f

-- | A wrapper for Barbie-types, providing useful instances.
newtype Barbie (b :: (k -> Type) -> Type) f
Barbie :: b f -> Barbie (b :: (k -> Type) -> Type) f
[getBarbie] :: Barbie (b :: (k -> Type) -> Type) f -> b f

-- | Uninhabited barbie type.
data Void (f :: k -> Type)

-- | A barbie type without structure.
data Unit (f :: k -> Type)
Unit :: Unit (f :: k -> Type)
newtype Rec (p :: Type) a x
Rec :: K1 R a x -> Rec (p :: Type) a x
[unRec] :: Rec (p :: Type) a x -> K1 R a x
class GProductB (f :: k -> Type) (g :: k -> Type) repbf repbg repbfg
gbprod :: GProductB f g repbf repbg repbfg => Proxy f -> Proxy g -> repbf x -> repbg x -> repbfg x
gbuniq :: (GProductB f g repbf repbg repbfg, f ~ g, repbf ~ repbg) => Proxy f -> Proxy repbf -> Proxy repbfg -> (forall a. f a) -> repbf x
class GProductBC c repbx repbd
gbdicts :: (GProductBC c repbx repbd, GAll 0 c repbx) => repbd x

-- | Like <a>bprod</a>, but returns a binary <a>Prod</a>, instead of
--   <a>Product</a>, which composes better.
--   
--   See <a>/*/</a> for usage.
(/*/) :: ProductB b => b f -> b g -> b (Prod '[f, g])
infixr 4 /*/

-- | Similar to <a>/*/</a> but one of the sides is already a
--   <tt><a>Prod</a> fs</tt>.
--   
--   Note that <a>/*</a>, <a>/*/</a> and <a>uncurryn</a> are meant to be
--   used together: <a>/*</a> and <a>/*/</a> combine <tt>b f1, b f2...b
--   fn</tt> into a single product that can then be consumed by using
--   <a>uncurryn</a> on an n-ary function. E.g.
--   
--   <pre>
--   f :: f a -&gt; g a -&gt; h a -&gt; i a
--   
--   <a>bmap</a> (<a>uncurryn</a> f) (bf <a>/*</a> bg <a>/*/</a> bh)
--   </pre>
(/*) :: ProductB b => b f -> b (Prod fs) -> b (Prod (f ': fs))
infixr 4 /*

module Barbies.Bi

-- | Map over both arguments at the same time.
btmap :: (FunctorB (b f), FunctorT b) => (forall a. f a -> f' a) -> (forall a. g a -> g' a) -> b f g -> b f' g'

-- | A version of <a>btmap</a> specialized to a single argument.
btmap1 :: (FunctorB (b f), FunctorT b) => (forall a. f a -> g a) -> b f f -> b g g

-- | Traverse over both arguments, first over <tt>f</tt>, then over
--   <tt>g</tt>..
bttraverse :: (TraversableB (b f), TraversableT b, Monad t) => (forall a. f a -> t (f' a)) -> (forall a. g a -> t (g' a)) -> b f g -> t (b f' g')

-- | A version of <a>bttraverse</a> specialized to a single argument.
bttraverse1 :: (TraversableB (b f), TraversableT b, Monad t) => (forall a. f a -> t (g a)) -> b f f -> t (b g g)

-- | Map each element to an action, evaluate these actions from left to
--   right and ignore the results.
bttraverse_ :: (TraversableB (b f), TraversableT b, Monad e) => (forall a. f a -> e c) -> (forall a. g a -> e d) -> b f g -> e ()

-- | Map each element to a monoid, and combine the results.
btfoldMap :: (TraversableB (b f), TraversableT b, Monoid m) => (forall a. f a -> m) -> (forall a. g a -> m) -> b f g -> m

-- | Conceptually, this is like simultaneously using <a>bpure</a> and
--   <a>tpure</a>.
btpure :: (ApplicativeB (b Unit), FunctorT b) => (forall a. f a) -> (forall a. g a) -> b f g

-- | A version of <a>btpure</a> specialized to a single argument.
btpure1 :: (ApplicativeB (b Unit), FunctorT b) => (forall a. f a) -> b f f

-- | Simultaneous product on both arguments.
btprod :: (ApplicativeB (b (Alt (Product f f'))), FunctorT b, Alternative f, Alternative f') => b f g -> b f' g' -> b (f `Product` f') (g `Product` g')

-- | Convert a <a>FunctorB</a> into a <a>FunctorT</a> and vice-versa.
newtype Flip b l r
Flip :: b r l -> Flip b l r
[runFlip] :: Flip b l r -> b r l
instance forall k1 k2 (b :: k2 -> k1 -> *) (l :: k1) (r :: k2). GHC.Show.Show (b r l) => GHC.Show.Show (Barbies.Bi.Flip b l r)
instance forall k1 k2 (b :: k2 -> k1 -> *) (l :: k1) (r :: k2). GHC.Read.Read (b r l) => GHC.Read.Read (Barbies.Bi.Flip b l r)
instance forall k1 k2 (b :: k2 -> k1 -> *) (l :: k1) (r :: k2). GHC.Classes.Ord (b r l) => GHC.Classes.Ord (Barbies.Bi.Flip b l r)
instance forall k1 k2 (b :: k2 -> k1 -> *) (l :: k1) (r :: k2). GHC.Classes.Eq (b r l) => GHC.Classes.Eq (Barbies.Bi.Flip b l r)
instance forall k1 k2 (b :: (k1 -> *) -> k2 -> *) (f :: k2). Barbies.Internal.FunctorT.FunctorT b => Barbies.Internal.FunctorB.FunctorB (Barbies.Bi.Flip b f)
instance forall k (b :: (* -> *) -> k -> *) (f :: k). Barbies.Internal.DistributiveT.DistributiveT b => Barbies.Internal.DistributiveB.DistributiveB (Barbies.Bi.Flip b f)
instance forall k1 k2 (b :: (k1 -> *) -> k2 -> *) (f :: k2). Barbies.Internal.TraversableT.TraversableT b => Barbies.Internal.TraversableB.TraversableB (Barbies.Bi.Flip b f)
instance forall k1 k2 (b :: (k1 -> *) -> k2 -> *) (f :: k2). Barbies.Internal.ApplicativeT.ApplicativeT b => Barbies.Internal.ApplicativeB.ApplicativeB (Barbies.Bi.Flip b f)
instance forall k' k (b :: k' -> (k -> *) -> *). (forall (f :: k'). Barbies.Internal.FunctorB.FunctorB (b f)) => Barbies.Internal.FunctorT.FunctorT (Barbies.Bi.Flip b)
instance forall i (b :: i -> (* -> *) -> *). (forall (f :: i). Barbies.Internal.DistributiveB.DistributiveB (b f)) => Barbies.Internal.DistributiveT.DistributiveT (Barbies.Bi.Flip b)
instance forall k' k (b :: k' -> (k -> *) -> *). (forall (f :: k'). Barbies.Internal.TraversableB.TraversableB (b f)) => Barbies.Internal.TraversableT.TraversableT (Barbies.Bi.Flip b)
instance forall k' k (b :: k' -> (k -> *) -> *). (forall (f :: k'). Barbies.Internal.ApplicativeB.ApplicativeB (b f)) => Barbies.Internal.ApplicativeT.ApplicativeT (Barbies.Bi.Flip b)


-- | A common Haskell idiom is to parameterise a datatype by a functor or
--   GADT (or any "indexed type" <tt>k -&gt; <a>Type</a></tt>), a pattern
--   sometimes called <a>HKD</a>). This parameter acts like the outfit of a
--   Barbie, turning it into a different doll. The canonical example would
--   be:
--   
--   <pre>
--   data Person f
--     = Person
--         { name :: f <a>String</a>
--         , age  :: f <a>Int</a>
--         }
--   </pre>
--   
--   Let's say that we are writing an application where <tt>Person</tt>
--   data will be read from a web form, validated, and stored in a
--   database. Some possibles outfits that we could use along the way are:
--   
--   <pre>
--   Person (<a>Const</a> <a>String</a>)  -- for the raw input from the web-form,
--   Person (<a>Either</a> <a>String</a>) -- for the result of parsing and validating,
--   Person <a>Identity</a>        -- for the actual data,
--   Person DbColumn        -- To describe how to read / write a <tt>Person</tt> to the db
--   
--   data DbColumn a
--     = DbColumn
--         { colName :: <a>String</a>
--         , fromDb  :: DbDataParser a
--         , toDb    :: a -&gt; DbData
--         }
--   </pre>
--   
--   In such application it is likely that one will have lots of types like
--   <tt>Person</tt> so we will like to handle these transformations
--   uniformly, without boilerplate or repetitions. This package provides
--   classes to manipulate these types, using notions that are familiar to
--   haskellers like <a>Functor</a>, <a>Applicative</a> or
--   <a>Traversable</a>. For example, instead of writing an ad-hoc function
--   that checks that all fields have a correct value, like
--   
--   <pre>
--   checkPerson :: Person (<a>Either</a> <a>String</a>) -&gt; <a>Either</a> [<a>String</a>] (Person <a>Identity</a>)
--   </pre>
--   
--   we can write only one such function:
--   
--   <pre>
--   check :: <a>TraversableB</a> b =&gt; b (<a>Either</a> <a>String</a>) -&gt; <a>Either</a> [<a>String</a>] (b <a>Identity</a>)
--   check be
--     = case <a>btraverse</a> (<a>either</a> (<a>const</a> <a>Nothing</a>) (<a>Just</a> . <a>Identity</a>)) be of
--         <a>Just</a> bi -&gt; <a>Right</a> bi
--         <a>Nothing</a> -&gt; <a>Left</a> (<a>bfoldMap</a> (<a>either</a> (:[]) (<a>const</a> [])) be)
--   </pre>
--   
--   Moreover, these classes come with default instances based on
--   <a>Generic</a>, so using them is as easy as:
--   
--   <pre>
--   data Person f
--     = Person
--         { name :: f <a>String</a>
--         , age  :: f <a>Int</a>
--         }
--     deriving
--       ( <a>Generic</a>
--       , <a>FunctorB</a>, <a>TraversableB</a>, <a>ApplicativeB</a>, <a>ConstraintsB</a>
--       )
--   
--   deriving instance <a>AllBF</a> <a>Show</a> f Person =&gt; <a>Show</a> (Person f)
--   deriving instance <a>AllBF</a> <a>Eq</a>   f Person =&gt; <a>Eq</a>   (Person f)
--   </pre>
module Barbies

-- | Wrapper for barbies that act as containers of <tt>a</tt> by wearing
--   <tt>(<a>Const</a> a)</tt>.
newtype Container b a
Container :: b (Const a) -> Container b a
[getContainer] :: Container b a -> b (Const a)

-- | Wrapper for barbies that act as containers of <tt>e</tt> by wearing
--   <tt><a>Either</a> e</tt>.
newtype ErrorContainer b e
ErrorContainer :: b (Either e) -> ErrorContainer b e
[getErrorContainer] :: ErrorContainer b e -> b (Either e)

-- | A wrapper for Barbie-types, providing useful instances.
newtype Barbie (b :: (k -> Type) -> Type) f
Barbie :: b f -> Barbie (b :: (k -> Type) -> Type) f
[getBarbie] :: Barbie (b :: (k -> Type) -> Type) f -> b f

-- | Uninhabited barbie type.
data Void (f :: k -> Type)

-- | A barbie type without structure.
data Unit (f :: k -> Type)
Unit :: Unit (f :: k -> Type)


-- | Support for operating on Barbie-types with constrained functions.
module Barbies.Constraints

-- | <tt><a>Dict</a> c a</tt> is evidence that there exists an instance of
--   <tt>c a</tt>.
--   
--   It is essentially equivalent to <tt>Dict (c a)</tt> from the
--   <a>constraints</a> package, but because of its kind, it allows us to
--   define things like <tt><a>Dict</a> <a>Show</a></tt>.
data Dict c a
[Dict] :: c a => Dict c a

-- | Turn a constrained-function into an unconstrained one that uses the
--   packed instance dictionary instead.
requiringDict :: (c a => r) -> Dict c a -> r

-- | Similar to <a>AllB</a> but will put the functor argument <tt>f</tt>
--   between the constraint <tt>c</tt> and the type <tt>a</tt>. For
--   example:
--   
--   <pre>
--   <a>AllB</a>  <a>Show</a>   Person ~ (<a>Show</a>    <a>String</a>,  <a>Show</a>    <a>Int</a>)
--   <a>AllBF</a> <a>Show</a> f Person ~ (<a>Show</a> (f <a>String</a>), <a>Show</a> (f <a>Int</a>))
--   
--   </pre>
type AllBF c f b = AllB (ClassF c f) b

-- | <a>ClassF</a> has one universal instance that makes <tt><a>ClassF</a>
--   c f a</tt> equivalent to <tt>c (f a)</tt>. However, we have
--   
--   <pre>
--   'ClassF c f :: k -&gt; <a>Constraint</a>
--   </pre>
--   
--   This is useful since it allows to define constraint-constructors like
--   <tt><a>ClassF</a> <a>Monoid</a> <a>Maybe</a></tt>
class c (f a) => ClassF c f a

-- | Like <a>ClassF</a> but for binary relations.
class c (f a) (g a) => ClassFG c f g a

module Barbies.Internal

-- | Default implementation of <a>bmap</a> based on <a>Generic</a>.
gbmapDefault :: CanDeriveFunctorB b f g => (forall a. f a -> g a) -> b f -> b g
class GFunctor (n :: Nat) f g repbf repbg
gmap :: GFunctor n f g repbf repbg => Proxy n -> (forall a. f a -> g a) -> repbf x -> repbg x

-- | <tt><a>CanDeriveFunctorB</a> B f g</tt> is in practice a predicate
--   about <tt>B</tt> only. Intuitively, it says that the following holds,
--   for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (B f)</tt>.</li>
--   <li><tt>B f</tt> can contain fields of type <tt>b f</tt> as long as
--   there exists a <tt><a>FunctorB</a> b</tt> instance. In particular,
--   recursive usages of <tt>B f</tt> are allowed.</li>
--   <li><tt>B f</tt> can also contain usages of <tt>b f</tt> under a
--   <tt><a>Functor</a> h</tt>. For example, one could use <tt><a>Maybe</a>
--   (B f)</tt> when defining <tt>B f</tt>.</li>
--   </ul>
type CanDeriveFunctorB b f g = (GenericP 0 (b f), GenericP 0 (b g), GFunctor 0 f g (RepP 0 (b f)) (RepP 0 (b g)))

-- | <tt><a>CanDeriveFunctorT</a> T f g x</tt> is in practice a predicate
--   about <tt>T</tt> only. Intuitively, it says that the following holds,
--   for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (T f)</tt>.</li>
--   <li><tt>T f x</tt> can contain fields of type <tt>t f y</tt> as long
--   as there exists a <tt><a>FunctorT</a> t</tt> instance. In particular,
--   recursive usages of <tt>T f y</tt> are allowed.</li>
--   <li><tt>T f x</tt> can also contain usages of <tt>t f y</tt> under a
--   <tt><a>Functor</a> h</tt>. For example, one could use <tt><a>Maybe</a>
--   (T f y)</tt> when defining <tt>T f y</tt>.</li>
--   </ul>
type CanDeriveFunctorT t f g x = (GenericP 1 (t f x), GenericP 1 (t g x), GFunctor 1 f g (RepP 1 (t f x)) (RepP 1 (t g x)))

-- | Default implementation of <a>btraverse</a> based on <a>Generic</a>.
gbtraverseDefault :: forall b f g e. (Applicative e, CanDeriveTraversableB b f g) => (forall a. f a -> e (g a)) -> b f -> e (b g)
class GTraversable n f g repbf repbg
gtraverse :: (GTraversable n f g repbf repbg, Applicative t) => Proxy n -> (forall a. f a -> t (g a)) -> repbf x -> t (repbg x)

-- | <tt><a>CanDeriveTraversableB</a> B f g</tt> is in practice a predicate
--   about <tt>B</tt> only. It is analogous to <a>CanDeriveFunctorB</a>, so
--   it essentially requires the following to hold, for any arbitrary
--   <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (B f)</tt>.</li>
--   <li><tt>B f</tt> can contain fields of type <tt>b f</tt> as long as
--   there exists a <tt><a>TraversableB</a> b</tt> instance. In particular,
--   recursive usages of <tt>B f</tt> are allowed.</li>
--   <li><tt>B f</tt> can also contain usages of <tt>b f</tt> under a
--   <tt><a>Traversable</a> h</tt>. For example, one could use
--   <tt><a>Maybe</a> (B f)</tt> when defining <tt>B f</tt>.</li>
--   </ul>
type CanDeriveTraversableB b f g = (GenericP 0 (b f), GenericP 0 (b g), GTraversable 0 f g (RepP 0 (b f)) (RepP 0 (b g)))

-- | <tt><a>CanDeriveTraversableT</a> T f g x</tt> is in practice a
--   predicate about <tt>T</tt> only. It is analogous to
--   <a>CanDeriveFunctorT</a>, so it essentially requires the following to
--   hold, for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (T f x)</tt>.</li>
--   <li><tt>T f x</tt> can contain fields of type <tt>t f x</tt> as long
--   as there exists a <tt><a>TraversableT</a> t</tt> instance. In
--   particular, recursive usages of <tt>T f x</tt> are allowed.</li>
--   <li><tt>T f x</tt> can also contain usages of <tt>t f x</tt> under a
--   <tt><a>Traversable</a> h</tt>. For example, one could use
--   <tt><a>Maybe</a> (T f x)</tt> when defining <tt>T f x</tt>.</li>
--   </ul>
type CanDeriveTraversableT t f g x = (GenericP 1 (t f x), GenericP 1 (t g x), GTraversable 1 f g (RepP 1 (t f x)) (RepP 1 (t g x)))

-- | Default implementation of <a>bdistribute</a> based on <a>Generic</a>.
gbdistributeDefault :: CanDeriveDistributiveB b f g => Functor f => f (b g) -> b (Compose f g)
class (Functor f) => GDistributive (n :: Nat) f repbg repbfg
gdistribute :: GDistributive n f repbg repbfg => Proxy n -> f (repbg x) -> repbfg x

-- | <tt><a>CanDeriveDistributiveB</a> B f g</tt> is in practice a
--   predicate about <tt>B</tt> only. Intuitively, it says the the
--   following holds for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (B f)</tt>.</li>
--   <li><tt>(B f)</tt> has only one constructor, and doesn't contain
--   "naked" fields (that is, not covered by <tt>f</tt>).</li>
--   <li><tt>B f</tt> can contain fields of type <tt>b f</tt> as long as
--   there exists a <tt><a>DistributiveB</a> b</tt> instance. In
--   particular, recursive usages of <tt>B f</tt> are allowed.</li>
--   <li><tt>B f</tt> can also contain usages of <tt>b f</tt> under a
--   <tt><a>Distributive</a> h</tt>. For example, one could use <tt>a -&gt;
--   (B f)</tt> as a field of <tt>B f</tt>.</li>
--   </ul>
type CanDeriveDistributiveB b f g = (GenericP 0 (b g), GenericP 0 (b (Compose f g)), GDistributive 0 f (RepP 0 (b g)) (RepP 0 (b (Compose f g))))

-- | <tt><a>CanDeriveDistributiveT</a> T f g x</tt> is in practice a
--   predicate about <tt>T</tt> only. Intuitively, it says the the
--   following holds for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (B f x)</tt>.</li>
--   <li><tt>(B f x)</tt> has only one constructor, and doesn't contain
--   "naked" fields (that is, not covered by <tt>f</tt>). In particular,
--   <tt>x</tt> needs to occur under <tt>f</tt>.</li>
--   <li><tt>B f x</tt> can contain fields of type <tt>b f y</tt> as long
--   as there exists a <tt><a>DistributiveT</a> b</tt> instance. In
--   particular, recursive usages of <tt>B f x</tt> are allowed.</li>
--   <li><tt>B f x</tt> can also contain usages of <tt>b f y</tt> under a
--   <tt><a>Distributive</a> h</tt>. For example, one could use <tt>a -&gt;
--   (B f x)</tt> as a field of <tt>B f x</tt>.</li>
--   </ul>
type CanDeriveDistributiveT (t :: (Type -> Type) -> i -> Type) f g x = (GenericP 1 (t g x), GenericP 1 (t (Compose f g) x), GDistributive 1 f (RepP 1 (t g x)) (RepP 1 (t (Compose f g) x)))
gbpureDefault :: forall b f. CanDeriveApplicativeB b f f => (forall a. f a) -> b f

-- | Default implementation of <a>bprod</a> based on <a>Generic</a>.
gbprodDefault :: forall b f g. CanDeriveApplicativeB b f g => b f -> b g -> b (f `Product` g)
class GApplicative n (f :: k -> Type) (g :: k -> Type) repbf repbg repbfg
gprod :: GApplicative n f g repbf repbg repbfg => Proxy n -> Proxy f -> Proxy g -> repbf x -> repbg x -> repbfg x
gpure :: (GApplicative n f g repbf repbg repbfg, f ~ g, repbf ~ repbg) => Proxy n -> Proxy f -> Proxy repbf -> Proxy repbfg -> (forall a. f a) -> repbf x

-- | <tt><a>CanDeriveApplicativeB</a> B f g</tt> is in practice a predicate
--   about <tt>B</tt> only. Intuitively, it says that the following holds,
--   for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (B f)</tt>.</li>
--   <li><tt>B</tt> has only one constructor (that is, it is not a
--   sum-type).</li>
--   <li>Every field of <tt>B f</tt> is either a monoid, or of the form
--   <tt>f a</tt>, for some type <tt>a</tt>.</li>
--   </ul>
type CanDeriveApplicativeB b f g = (GenericP 0 (b f), GenericP 0 (b g), GenericP 0 (b (f `Product` g)), GApplicative 0 f g (RepP 0 (b f)) (RepP 0 (b g)) (RepP 0 (b (f `Product` g))))

-- | <tt><a>CanDeriveApplicativeT</a> T f g x</tt> is in practice a
--   predicate about <tt>T</tt> only. Intuitively, it says that the
--   following holds, for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (T f)</tt>.</li>
--   <li><tt>T</tt> has only one constructor (that is, it is not a
--   sum-type).</li>
--   <li>Every field of <tt>T f x</tt> is either a monoid, or of the form
--   <tt>f a</tt>, for some type <tt>a</tt>.</li>
--   </ul>
type CanDeriveApplicativeT t f g x = (GenericP 1 (t f x), GenericP 1 (t g x), GenericP 1 (t (f `Product` g) x), GApplicative 1 f g (RepP 1 (t f x)) (RepP 1 (t g x)) (RepP 1 (t (f `Product` g) x)))

-- | Default implementation of <a>baddDicts</a> based on <a>Generic</a>.
gbaddDictsDefault :: forall b c f. (CanDeriveConstraintsB c b f, AllB c b) => b f -> b (Dict c `Product` f)
class GConstraints n c f repbx repbf repbdf
gaddDicts :: (GConstraints n c f repbx repbf repbdf, GAll n c repbx) => repbf x -> repbdf x

-- | <tt><a>CanDeriveConstraintsB</a> B f g</tt> is in practice a predicate
--   about <tt>B</tt> only. Intuitively, it says that the following holds,
--   for any arbitrary <tt>f</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (B f)</tt>.</li>
--   <li><tt>B f</tt> can contain fields of type <tt>b f</tt> as long as
--   there exists a <tt><a>ConstraintsB</a> b</tt> instance. In particular,
--   recursive usages of <tt>B f</tt> are allowed.</li>
--   </ul>
type CanDeriveConstraintsB c b f = (GenericN (b f), GenericN (b (Dict c `Product` f)), AllB c b ~ GAll 0 c (GAllRepB b), GConstraints 0 c f (GAllRepB b) (RepN (b f)) (RepN (b (Dict c `Product` f))))

-- | <tt><a>CanDeriveConstraintsT</a> T f g x</tt> is in practice a
--   predicate about <tt>T</tt> only. Intuitively, it says that the
--   following holds, for any arbitrary <tt>f</tt> and <tt>x</tt>:
--   
--   <ul>
--   <li>There is an instance of <tt><a>Generic</a> (T f x)</tt>.</li>
--   <li><tt>T f</tt> can contain fields of type <tt>t f x</tt> as long as
--   there exists a <tt><a>ConstraintsT</a> t</tt> instance. In particular,
--   recursive usages of <tt>T f x</tt> are allowed.</li>
--   </ul>
type CanDeriveConstraintsT c t f x = (GenericN (t f x), GenericN (t (Dict c `Product` f) x), AllT c t ~ GAll 1 c (GAllRepT t), GConstraints 1 c f (GAllRepT t) (RepN (t f x)) (RepN (t (Dict c `Product` f) x)))
type family GAll (n :: Nat) (c :: k -> Constraint) (repbf :: Type -> Type) :: Constraint

-- | The representation used for the generic computation of the
--   <tt><a>AllB</a> c b</tt> constraints.
type GAllRepB b = TagSelf0 b

-- | The representation used for the generic computation of the
--   <tt><a>AllT</a> c t</tt> constraints. .
type GAllRepT t = TagSelf1 t
data X a
data family Y :: k
data Self (p :: Type) (a :: Type) (x :: Type)
data Other (p :: Type) (a :: Type) (x :: Type)
type family SelfOrOther (b :: k) (b' :: k) :: Type -> Type -> Type -> Type

-- | We use the type-families to generically compute <tt><a>AllB</a> c
--   b</tt>. Intuitively, if <tt>b' f'</tt> occurs inside <tt>b f</tt>,
--   then we should just add <tt><a>AllB</a> b' c</tt> to <tt><a>AllB</a> b
--   c</tt>. The problem is that if <tt>b</tt> is a recursive type, and
--   <tt>b'</tt> is <tt>b</tt>, then ghc will choke and blow the stack
--   (instead of computing a fixpoint).
--   
--   So, we would like to behave differently when <tt>b = b'</tt> and add
--   <tt>()</tt> instead of <tt><a>AllB</a> b c</tt> to break the
--   recursion. Our trick will be to use a type family to inspect
--   <tt><a>Rep</a> (b X)</tt>, for an arbitrary <tt>X</tt>, and
--   distinguish recursive usages from non-recursive ones, tagging them
--   with different types, so we can distinguish them in the instances.
type TagSelf0 b = TagSelf0' (Indexed b 1) (RepN (b X))
type family TagSelf0' (b :: kf -> Type) (repbf :: Type -> Type) :: Type -> Type

-- | We use the type-families to generically compute <tt><a>AllT</a> c
--   b</tt>. Intuitively, if <tt>t' f' x'</tt> occurs inside <tt>t f
--   x</tt>, then we should just add <tt><a>AllT</a> t' c</tt> to
--   <tt><a>AllT</a> t c</tt>. The problem is that if <tt>t</tt> is a
--   recursive type, and <tt>t'</tt> is <tt>t</tt>, then ghc will choke and
--   blow the stack (instead of computing a fixpoint).
--   
--   So, we would like to behave differently when <tt>t = t'</tt> and add
--   <tt>()</tt> instead of <tt><a>AllT</a> t c</tt> to break the
--   recursion. Our trick will be to use a type family to inspect
--   <tt><a>Rep</a> (t X Y)</tt>, for arbitrary <tt>X</tt> and <tt>Y</tt>
--   and distinguish recursive usages from non-recursive ones, tagging them
--   with different types, so we can distinguish them in the instances.
type TagSelf1 b = TagSelf1' (Indexed b 2) (Zip (Rep (Indexed (b X) 1 Y)) (Rep (b X Y)))
type family TagSelf1' (b :: kf -> kg -> Type) (repbf :: Type -> Type) :: Type -> Type

-- | Default implementation of <a>bstrip</a> based on <a>Generic</a>.
gbcoverDefault :: CanDeriveBareB b => b Bare Identity -> b Covered Identity

-- | Default implementation of <a>bstrip</a> based on <a>Generic</a>.
gbstripDefault :: CanDeriveBareB b => b Covered Identity -> b Bare Identity
class GBare (n :: Nat) repbi repbb
gstrip :: GBare n repbi repbb => Proxy n -> repbi x -> repbb x
gcover :: GBare n repbi repbb => Proxy n -> repbb x -> repbi x

-- | All types that admit a generic <a>FunctorB</a> instance, and have all
--   their occurrences of <tt>f</tt> under a <a>Wear</a> admit a generic
--   <a>BareB</a> instance.
type CanDeriveBareB b = (GenericP 0 (b Bare Identity), GenericP 0 (b Covered Identity), GBare 0 (RepP 0 (b Covered Identity)) (RepP 0 (b Bare Identity)))
data family Param (n :: Nat) (a :: k) :: k
type family Indexed (t :: k) (i :: Nat) :: k
type family FilterIndex (n :: Nat) (t :: k) :: k
type family Zip (a :: Type -> Type) (b :: Type -> Type) :: Type -> Type
newtype Rec (p :: Type) a x
Rec :: K1 R a x -> Rec (p :: Type) a x
[unRec] :: Rec (p :: Type) a x -> K1 R a x
class (Coercible (Rep a) (RepN a), Generic a) => GenericN (a :: Type) where {
    type RepN (a :: Type) :: Type -> Type;
    type RepN a = Zip (Rep (Indexed a 0)) (Rep a);
}
toN :: GenericN a => RepN a x -> a
fromN :: GenericN a => a -> RepN a x
class (Coercible (Rep a) (RepP n a), Generic a) => GenericP (n :: Nat) (a :: Type) where {
    type RepP n a :: Type -> Type;
    type RepP n a = Zip (Rep (FilterIndex n (Indexed a 0))) (Rep a);
}
toP :: GenericP n a => Proxy n -> RepP n a x -> a
fromP :: GenericP n a => Proxy n -> a -> RepP n a x
