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


-- | Work generically on your datatype without knowing its shape nor its contents.
--   
--   Work generically on your datatype without knowing its shape nor its
--   contents using a principlied approach.
@package flay
@version 0.4


-- | The most commonly used names in this module are intended to be
--   imported unqualified, as necessary:
--   
--   <pre>
--   import Flay (Flay, Flayable(flay), Flayable1(flay1))
--   </pre>
--   
--   The rest of the names, qualified:
--   
--   <pre>
--   import qualified Flay
--   </pre>
module Flay

-- | <tt><a>Flay</a> c s t f g</tt> allows converting <tt>s</tt> to
--   <tt>t</tt> by replacing ocurrences of <tt>f</tt> with <tt>g</tt> by
--   applicatively applying a function <tt>(forall a. c a =&gt; f a -&gt; m
--   (g a))</tt> to targeted occurences of <tt>f a</tt> inside <tt>s</tt>.
--   
--   A <a>Flay</a> must obey the following identity law:
--   
--   <pre>
--   forall (fl :: <a>Flay</a> c s t f g).
--      fl (<a>const</a> <a>pure</a>)  ==  <a>pure</a>
--   </pre>
--   
--   When defining <a>Flay</a> values, you should leave <tt>c</tt>,
--   <tt>f</tt>, and <tt>g</tt> fully polymorphic, as these are the most
--   useful types of <a>Flay</a>s.
--   
--   We use <tt><a>Dict</a> (c a) -&gt;</tt> instead of <tt>c a =&gt;</tt>
--   because the latter is often not enough to satisfy the type checker.
--   With this approach, one must explicitly pattern match on the
--   <tt><a>Dict</a> (c a)</tt> constructor in order to bring the <tt>c
--   a</tt> instance to scope. Also, it's necessary that <tt>c</tt> is
--   explicitly given a type at the <tt>Flay'</tt>s call site, as otherwise
--   the type checker won't be able to infer <tt>c</tt> on its own.
--   
--   <i>to flay: tr. v., to strip off the skin or surface of.</i>
--   
--   Mnemonic for <tt>c s t f g</tt>: Much like lenses have type indexes
--   <tt>s t a b</tt> where <tt>s</tt> is the input state, <tt>t</tt> is
--   the output state, and <tt>a</tt> and <tt>b</tt> are the input and
--   output <i>values</i> respectively, in <a>Flay</a>, <tt>s</tt> and
--   <tt>t</tt> represent the input and output states like in lenses, and
--   <tt>f</tt> and <tt>g</tt> represent the <i>wrappers</i> over the input
--   and output values respectively. The <tt>c</tt> comes at the very
--   beginning because it is the type you are expected to apply with
--   <tt>TypeApplications</tt> if necessary.
--   
--   <h4>Example 1: Removing uncertainty</h4>
--   
--   Consider the following types and values:
--   
--   <pre>
--   data Foo f = Foo (f <a>Int</a>) (f <a>Bool</a>)
--   
--   deriving instance (<a>Show</a> (f <a>Int</a>), <a>Show</a> (f <a>Bool</a>)) =&gt; <a>Show</a> (Foo f)
--   </pre>
--   
--   <pre>
--   flayFoo :: (<a>Applicative</a> m, c <a>Int</a>, c <a>Bool</a>) =&gt; <a>Flay</a> c (Foo f) (Foo g) f g
--   flayFoo h (Foo a b) = Foo &lt;$&gt; h <a>Dict</a> a &lt;*&gt; h <a>Dict</a> b
--   </pre>
--   
--   <pre>
--   foo1 :: Foo <a>Maybe</a>
--   foo1 = Foo (<a>Just</a> 1) <a>Nothing</a>
--   </pre>
--   
--   <pre>
--   foo2 :: Foo <a>Maybe</a>
--   foo2 = Foo (<a>Just</a> 2) (<a>Just</a> <a>True</a>)
--   </pre>
--   
--   It is possible to remove the <i>uncertainty</i> of the fields in
--   <tt>Foo</tt> perhaps being empty (<a>Nothing</a>) by converting
--   <tt>Foo <a>Maybe</a></tt> to <tt>Foo <tt>Identity</tt></tt>. However,
--   we can't just write a function of type <tt>Foo <a>Maybe</a> -&gt; Foo
--   <tt>Identity</tt></tt> because we have the possiblity of some of the
--   fields being <a>Nothing</a>, like in <tt>foo1</tt>. Instead, we are
--   looking for a function <tt>Foo <a>Maybe</a> -&gt; <a>Maybe</a> (Foo
--   <tt>Identity</tt>)</tt> which will result on <a>Just</a> only as long
--   as all of the fields in <tt>Foo</tt> is <a>Just</a>, like in
--   <tt>foo2</tt>. This is exactly what <a>Applicative</a> enables us to
--   do:
--   
--   <pre>
--   fooMaybeToIdentity :: Foo <a>Maybe</a> -&gt; <a>Maybe</a> (Foo <tt>Identity</tt>)
--   fooMaybeToIdentity (Foo a b) = Foo &lt;$&gt; <a>fmap</a> <a>pure</a> a &lt;*&gt; <a>fmap</a> <a>pure</a> b
--   </pre>
--   
--   Example using this in GHCi:
--   
--   <pre>
--   &gt; fooMaybeToIdentity foo1
--   <a>Nothing</a>
--   </pre>
--   
--   <pre>
--   &gt; fooMaybeToIdentity foo2
--   <a>Just</a> (Foo (<tt>Identity</tt> 2) (<tt>Identity</tt> <a>True</a>))
--   </pre>
--   
--   In fact, notice that we are not really working with <a>Just</a>,
--   <a>Nothing</a>, nor <tt>Identity</tt> directly, so we might as well
--   just leave <a>Maybe</a> and <tt>Identity</tt> polymorphic. All we need
--   is that they both are <a>Applicative</a>s:
--   
--   <pre>
--   fooMToG :: (<a>Applicative</a> m, <a>Applicative</a> g) =&gt; Foo m -&gt; m (Foo g)
--   fooMToG (Foo a b) = Foo &lt;$&gt; <a>fmap</a> <a>pure</a> a &lt;*&gt; <a>fmap</a> <a>pure</a> b
--   </pre>
--   
--   <tt>fooMToG</tt> behaves the same as <tt>fooMaybeToIdentity</tt>, but
--   more importantly, it is much more flexible:
--   
--   <pre>
--   &gt; fooMToG foo2 :: <a>Maybe</a> (Foo [])
--   <a>Just</a> (Foo [2] [<a>True</a>])
--   </pre>
--   
--   <pre>
--   &gt; fooMToG foo2 :: <a>Maybe</a> (Foo (<a>Either</a> <a>String</a>))
--   <a>Just</a> (Foo (<a>Right</a> 2) (<a>Right</a> <a>True</a>))
--   </pre>
--   
--   <a>Flay</a>, among other things, is intended to generalize this
--   pattern, so that whatever choice of <tt>Foo</tt>, <a>Maybe</a> or
--   <tt>Identity</tt> you make, you can use <a>Applicative</a> this way.
--   The easiest way to use <a>Flay</a> is through <a>trivial'</a>, which
--   is sufficient unless we need to enforce some constraint in the target
--   elements wrapped in <tt>m</tt> inside foo (we don't need this now).
--   With <a>trivial'</a>, we could have defined <tt>fooMToG</tt> this way:
--   
--   <pre>
--   fooMToG :: (<a>Applicative</a> m, <a>Applicative</a> g) =&gt; Foo m -&gt; m (Foo g)
--   fooMToG = <a>trivial'</a> flayFoo (<a>fmap</a> <a>pure</a>)
--   </pre>
--   
--   Some important things to notice here are that we are reusing
--   <tt>flayFoo'</tt>s knowledge of <tt>Foo'</tt>s structure, and that the
--   construction of <tt>g</tt> using <a>pure</a> applies to <i>any</i>
--   value wrapped in <tt>m</tt> (<a>Int</a> and <a>Bool</a> in our case).
--   Compare this last fact to <a>traverse</a>, where the types of the
--   targets must be the same, and known beforehand.
--   
--   Also, notice that we inlined <tt>flayFoo</tt> for convenience in this
--   example, but we could as well have taken it as an argument,
--   illustrating even more how <a>Flay</a> decouples the shape and targets
--   from their processing:
--   
--   <pre>
--   flayMToG :: (<a>Applicative</a> m, <a>Applicative</a> g) =&gt; <a>Flay</a> <a>Trivial</a> m s t m g -&gt; s -&gt; m s
--   flayMToG fl = <a>trivial'</a> fl (<a>fmap</a> <a>pure</a>)
--   </pre>
--   
--   This is the esscence of <a>Flay</a>: We can work operating on the
--   contents of a datatype <tt>s</tt> targeted by a given <a>Flay</a>
--   <i>without</i> knowing anything about <tt>s</tt>, nor about the
--   <tt>forall x. f x</tt> targets of the <a>Flay</a>. And we do this
--   using an principled approach relying on <a>Applicative</a> and
--   <a>Functor</a>.
--   
--   We can use a <a>Flay</a> to repurpose a datatype while maintaining its
--   "shape". For example, given <tt>Foo</tt>: <tt>Foo
--   <tt>Identity</tt></tt> represents the presence of two values
--   <a>Int</a> and <a>Char</a>, <tt>Foo <a>Maybe</a></tt> represents their
--   potential absence, <tt>Foo []</tt> represents the potential for zero
--   or more <a>Int</a>s and <a>Char</a>s, <tt>Foo (<a>Const</a> x)</tt>
--   represent the presence of two values of type <tt>x</tt>, and <tt>Foo
--   <a>IO</a></tt> represents two <a>IO</a> actions necessary to obtain
--   values of type <a>Int</a> and <a>Char</a>. We can use <tt>flayFoo</tt>
--   to convert between these representations. In all these cases, the
--   shape of <tt>Foo</tt> is preserved, meaning we can continue to pattern
--   match or project on it. Notice that even though in this example the
--   <tt>f</tt> argument to <tt>Foo</tt> happens to always be a
--   <a>Functor</a>, this is not necessary at all.
--   
--   <h4>Example 2: Standalone <tt>m</tt></h4>
--   
--   In the previous example, <tt>flayFoo</tt> took the type <tt>Flay
--   <a>Trivial</a> (Foo m) (Foo g) m g</tt> when it was used in
--   <tt>flayMToG</tt>. That is, <tt>m</tt> and <tt>f</tt> were unified by
--   our use of <a>fmap</a>. However, keeping these different opens
--   interesting possibilities. For example, let's try and convert a
--   <tt>Foo <a>Maybe</a></tt> to a <tt>Foo (<a>Either</a>
--   <a>String</a>)</tt>, prompting the user for the <a>Left</a> side of
--   that <a>Either</a> whenever the original target value is missing.
--   
--   <pre>
--   prompt :: <a>IO</a> <a>String</a>
--   prompt = do
--     <a>putStr</a> "Missing value! Error message? "
--     <a>getLine</a>
--   </pre>
--   
--   <pre>
--   fooMaybeToEitherIO :: Foo <a>Maybe</a> -&gt; <a>IO</a> (Foo (<a>Either</a> <a>String</a>))
--   fooMaybeToEitherIO = <a>trivial'</a> flayFoo $ \case
--      <a>Nothing</a> -&gt; <a>fmap</a> <a>Left</a> <tt>prompt</tt>
--      <a>Just</a> x -&gt; <a>pure</a> (<a>Right</a> x)
--   </pre>
--   
--   Using this in GHCi:
--   
--   <pre>
--   &gt; fooMaybeToEitherIO foo1
--   Missing value! Error message? <i>Nooooo!!!!!</i>
--   Foo (<a>Right</a> 1) (<a>Left</a> "Nooooo!!!!!")
--   </pre>
--   
--   <pre>
--   &gt; fooMaybeToEitherIO foo2
--   Foo (<a>Right</a> 2) (<a>Right</a> <a>True</a>)
--   </pre>
--   
--   <h4>Example 3: Contexts</h4>
--   
--   Extending the previous example we "replaced" the missing values with a
--   <a>String</a>, but wouldn't it be nice if we could somehow prompt a
--   replacement value of the original type instead? That's what the
--   <tt>c</tt> argument to <a>Flay</a> is for. Let's replace
--   <tt>prompt</tt> so that it can construct a type other than
--   <a>String</a>:
--   
--   <pre>
--   prompt :: <a>Read</a> x =&gt; <a>IO</a> x
--   prompt = do
--     <a>putStr</a> "Missing value! Replacement? "
--     <a>readLn</a>
--   </pre>
--   
--   Notice how <tt>prompt</tt> now has a <tt><a>Read</a> x</tt>
--   constraint. In order to be able to use the result of <tt>prompt</tt>
--   as a replacement for our missing values in <tt>Foo <a>Maybe</a></tt>,
--   we will have to mention <a>Read</a> as the <tt>c</tt> argument to
--   <a>Flay</a>, which implies that <a>Read</a> will have to be a
--   constraint satisfied by all of the targets of our <a>Flay</a> (as seen
--   in the constraints in <tt>flayFoo</tt>). We can't use <a>trivial'</a>
--   anymore, we need to use <tt>flayFoo</tt> directly:
--   
--   <pre>
--   fooMaybeToIdentityIO :: Foo <a>Maybe</a> -&gt; <a>IO</a> (Foo <tt>Identity</tt>)
--   fooMaybeToIdentityIO = flayFoo h
--     where h :: <a>Dict</a> (<a>Read</a> a) -&gt; <a>Maybe</a> a -&gt; <a>IO</a> (<tt>Identity</tt> a)
--           h <a>Dict</a> = \case
--               <a>Nothing</a> -&gt; <a>fmap</a> <a>pure</a> prompt
--               <a>Just</a> a -&gt; <a>pure</a> (<a>pure</a> a)
--   </pre>
--   
--   Notice how we had to give an explicit type to our function <tt>h</tt>:
--   This is because can't infer our <tt><a>Read</a> a</tt> constraint. You
--   will always need to explicitly type the received <tt><a>Dict</a></tt>
--   unless the <tt>c</tt> argument to <a>Flay</a> has been explicitly by
--   other means (like in the definition of <a>trivial'</a>, where we don't
--   have to explicitly type <a>Dict</a> because <tt>c ~
--   <a>Trivial</a></tt> according to the top level signature of
--   <a>trivial'</a>). Using the <tt>TypeApplications</tt> GHC extension
--   might make things easier:
--   
--   <pre>
--   fooMaybeToIdentityIO :: Foo <a>Maybe</a> -&gt; <a>IO</a> (Foo <tt>Identity</tt>)
--   fooMaybeToIdentityIO = flayFoo @Read (\<a>Dict</a> -&gt; \case
--       <a>Nothing</a> -&gt; <a>fmap</a> <a>pure</a> prompt
--       <a>Just</a> a -&gt; <a>pure</a> (<a>pure</a> a))
--   </pre>
--   
--   Example using this in GHCi:
--   
--   <pre>
--   &gt; fooMaybeToIdentityIO foo1
--   Missing value! Replacement? <i><a>True</a></i>
--   Foo (<tt>Identity</tt> 1) (<tt>Identity</tt> <a>True</a>)
--   </pre>
--   
--   <pre>
--   &gt; fooMaybeToIdentityIO foo2
--   Foo (<tt>Identity</tt> 2) (<tt>Identity</tt> <a>True</a>)
--   </pre>
--   
--   Of course, as in our previous examples, <tt>Identity</tt> here could
--   have generalized to any <a>Applicative</a>. We just fixed it to
--   <tt>Identity</tt> as an example.
--   
--   You can mention as many constraints as you need in <tt>c</tt> as long
--   as <tt>c</tt> has kind <tt>k -&gt; <a>Constraint</a></tt> (where
--   <tt>k</tt> is the kind of <tt>f</tt>'s argument). You can always group
--   together many constraints as a single new one in order to achieve
--   this. For example, if you want to require both <a>Show</a> and
--   <a>Read</a> on your target types, then you can introduce the following
--   <tt>ShowAndRead</tt> class, and use that as your <tt>c</tt>.
--   
--   <pre>
--   class (<a>Show</a> a, <a>Read</a> a) =&gt; ShowAndRead a
--   instance (<a>Show</a> a, <a>Read</a> a) =&gt; ShowAndRead a
--   </pre>
--   
--   This is such a common scenario that the <a>Flay</a> module exports
--   <a>All</a>, a <a>Constraint</a> you can use to apply many
--   <a>Constraint</a>s at once. For example, instead of introducing
--   <tt>ShowAndRead</tt>, we could use <tt><a>All</a> '[<a>Show</a>,
--   <a>Read</a>]</tt> as our <tt>c</tt> argument to <a>Flay</a>, and the
--   net result would be the same.
--   
--   <h4>Example 4: <a>collect'</a></h4>
--   
--   See the documentation for <a>collect'</a>. To sum up: for any given
--   <a>Flay</a>, we can collect all of the <tt>Flay'</tt>s targets into a
--   <a>Monoid</a>, without knowing anything about the targets themselves
--   beyond the fact that they satisfy a particular constraint.
type Flay (c :: k -> Constraint) s t (f :: k -> *) (g :: k -> *) = forall m. Applicative m => (forall (a :: k). Dict (c a) -> f a -> m (g a)) -> s -> m t

-- | Default <a>Flay</a> implementation for <tt>s</tt> and <tt>t</tt>.
--   
--   When defining <a>Flayable</a> instances, you should leave <tt>c</tt>,
--   <tt>f</tt>, and <tt>g</tt> fully polymomrphic, as these are the most
--   useful types of <tt>Flayables</tt>s.
--   
--   If <tt>s</tt> and <tt>t</tt> are instances of <a>Generic</a>, then
--   <a>gflay</a> can be used as default implementation for <a>flay</a>.
--   For example, provided the following datatype and its <a>Generic</a>
--   instance:
--   
--   <pre>
--   data Foo f = Foo (f <a>Int</a>) (f <a>Bool</a>)
--     deriving (<a>Generic</a>)
--   </pre>
--   
--   Then the following <a>Flayable</a> instance would get a default
--   implementation for <a>flay</a>:
--   
--   <pre>
--   instance (c <a>Int</a>, c <a>Bool</a>) =&gt; <a>Flayable</a> c (Foo f) (Foo g) f g
--   </pre>
--   
--   But actually, this library exports an <tt>OVERLAPPABLE</tt> instance
--   that covers datatypes like <tt>Foo</tt> above. That is, datatypes
--   parametrized by some type constructor where that type constructor
--   wraps each of the immediate children fields. So <i>most times you
--   don't even need to write the <a>Flayable</a> instance yourself</i>.
--   That is, a <tt><a>Flayable</a> c (r f) (r g) f g</tt> for <tt>r</tt>
--   types parametrized by a type-constructor, such as <tt>Foo</tt>, having
--   <a>Generic</a> instances.
--   
--   In cases where you do need to define the <a>Flayable</a> instance
--   yourself, you'll notice that constraints applying <tt>c</tt> to every
--   immediate child field type will bubble up, such as <tt>(c <a>Int</a>,
--   c <a>Bool</a>)</tt> in the example above. This module exports the
--   <a>FieldsF</a> constraint that can be used to reduce that boilerplate
--   for datatypes that implement <a>Generic</a>, tackling all of the
--   fields at once. That is, the <a>Flayable</a> instance for <tt>Foo</tt>
--   above could have been written like this:
--   
--   <pre>
--   instance <a>FieldsF</a> c Foo =&gt; <a>Flayable</a> c (Foo f) (Foo g) f g
--   </pre>
--   
--   Notice that <a>flay</a> can be defined in terms of <a>flay1</a> as
--   well.
class Flayable (c :: k -> Constraint) s t (f :: k -> *) (g :: k -> *) | s -> f, t -> g, s g -> t, t f -> s
flay :: Flayable c s t f g => Flay c s t f g
flay :: (Flayable c s t f g, GFlay c s t f g) => Flay c s t f g

-- | <a>Flayable1</a> is <a>Flayable</a> specialized for the common case of
--   <tt>s ~ r f</tt> and <tt>t ~ r g</tt>. The rationale for introducing
--   this seemingly redundant constraint is that <a>Flayable1</a> is less
--   verbose than <a>Flayable</a>.
--   
--   In other words, if we had <tt>QuantifiedConstraints</tt>, then
--   <a>Flayable1</a> would be something like:
--   
--   <pre>
--   <a>Flayable1</a> c r
--      ==  forall (f :: k -&gt; *) (g :: k -&gt; *).
--             <a>Flayable</a> c (r f) (r g) f g
--   </pre>

-- | Like <a>flay</a>, but specialized to work on <a>Flayable1</a>.
flay1 :: forall c r f g. Flayable1 c r => Flay c (r f) (r g) f g
gflay :: GFlay c s t f g => Flay (c :: k -> Constraint) s t (f :: k -> *) (g :: k -> *)

-- | Convenient <a>Constraint</a> for satisfying the requirements of
--   <a>gflay</a>.
type GFlay (c :: k -> Constraint) s t (f :: k -> *) (g :: k -> *) = (GFlay' c (Rep s) (Rep t) f g, Generic s, Generic t)

-- | Ensure that <tt>x</tt> satisfies all of the constraints listed in
--   <tt>cs</tt>.

-- | <a>Constraint</a> trivially satisfied by every type.
--   
--   This can be used as the <tt>c</tt> parameter to <a>Flay</a> or
--   <a>Flayable</a> in case you are not interested in observing the values
--   inside <tt>f</tt>.
class Trivial (a :: k)

-- | Given a <a>Flay</a> for any constraint <tt>c</tt> obtain a <a>Flay</a>
--   for a <a>Trivial</a> constraint.
trivialize :: forall c s t f g. Flay c s t f g -> Flay Trivial s t f g

-- | Like <a>trivial'</a>, but works on a <a>Flayable</a> instead of taking
--   an explicit <a>Flay</a>.
--   
--   <pre>
--   <a>trivial</a> = <a>trivial'</a> <a>flay</a>
--   </pre>
trivial :: forall m s t f g. (Applicative m, Flayable Trivial s t f g) => (forall a. Trivial a => f a -> m (g a)) -> s -> m t

-- | Like <a>trivial'</a>, but works on a <a>Flayable1</a> instead of
--   taking an explicit <a>Flay</a>.
--   
--   <pre>
--   <a>trivial</a> = <a>trivial'</a> <a>flay1</a>
--   </pre>
trivial1 :: forall m f g r. (Applicative m, Flayable1 Trivial r) => (forall a. Trivial a => f a -> m (g a)) -> (r f) -> m (r g)

-- | You can use <a>trivial'</a> if you don't care about the <tt>c</tt>
--   argument to <a>Flay</a>. This implies that you won't be able to
--   observe the <tt>a</tt> in <tt>forall a. f a</tt>, all you can do with
--   such <tt>a</tt> is pass it around.
--   
--   <pre>
--   forall (fl :: <a>Flay</a> <a>Trivial</a> s t f g)
--          (h :: <a>Applicative</a> m =&gt; <a>Dict</a> <a>Trivial</a> -&gt; f a -&gt; m (g a)).
--   <a>trivial'</a> fl h  == fl (<a>const</a> h)
--   </pre>
trivial' :: forall m c s t f g. Applicative m => Flay c s t f g -> (forall a. Trivial a => f a -> m (g a)) -> s -> m t

-- | Like <a>collect'</a>, but works on a <a>Flayable</a> instead of an
--   explicit <a>Flay</a>.
collect :: (Monoid b, Flayable c s t f (Const ())) => (forall a. Dict (c a) -> f a -> b) -> s -> b

-- | Like <a>collect'</a>, but works on a <a>Flayable1</a> instead of an
--   explicit <a>Flay</a>.
collect1 :: (Monoid b, Flayable1 c r) => (forall a. Dict (c a) -> f a -> b) -> r f -> b

-- | Collect all of the <tt>f a</tt> of the given <a>Flay</a> into a
--   <a>Monoid</a> <tt>b</tt>.
--   
--   Example usage, given <tt>Foo</tt> and <tt>flayFoo</tt> examples given
--   in the documentation for <a>Flay</a>:
--   
--   <pre>
--   &gt; <a>collect'</a> flayFoo
--         (\(<a>Dict</a> :: <a>Dict</a> (<a>Show</a> a)) (<tt>Identity</tt> (a :: a)) -&gt; [<a>show</a> a])
--         (Foo (<a>pure</a> 4) (<a>pure</a> <a>True</a>))
--   ["4","True"]
--   </pre>
collect' :: Monoid b => Flay c s t f (Const ()) -> (forall a. Dict (c a) -> f a -> b) -> s -> b

-- | Zip two <a>Flayable</a>s together.
--   
--   <a>zip</a> is like <a>zip1</a>, but for <a>Flayable</a>s.
--   
--   Returns <a>Nothing</a> in case the indivual target types do not match.
--   
--   Note: <a>zip</a> is safer but less general than <a>unsafeZip</a>.
zip :: (Monad m, Typeable f, Flayable Typeable s1 t1 f (Const ()), Flayable Typeable s2 t2 g (Product f g), Flayable c t2 t3 (Product f g) h) => (forall x. Dict (c x) -> f x -> g x -> m (h x)) -> s1 -> s2 -> m (Maybe t3)

-- | Zip two <a>Flayable1</a>s together.
--   
--   Example pairing two of the <tt>Foo</tt> values seen elsewhere in this
--   file.
--   
--   <pre>
--   &gt; let foo1 = <tt>Foo</tt> (<a>Identity</a> 0) (<a>Identity</a> <a>False</a>)
--   &gt;   :: <tt>Foo</tt> <a>Identity</a>
--   
--   &gt; let foo2 = <tt>Foo</tt> (<a>Just</a> 1) <a>Nothing</a>
--   &gt;   :: <tt>Foo</tt> <a>Maybe</a>
--   
--   &gt; <a>zip1</a> ((<a>Dict</a> :: <a>Dict</a> (<a>Trivial</a> x)) a b -&gt; <a>Pair</a> a b) foo1 foo2
--   &gt;   :: <tt>Foo</tt> (<a>Product</a> <a>Identity</a> <a>Maybe</a>)
--   <tt>Foo</tt> (<a>Pair</a> (<a>Identity</a> 0) (<a>Just</a> 1)) (<a>Pair</a> (<a>Identity</a> <a>False</a>) <a>Nothing</a>)
--   
--   &gt; <a>zip1</a> ((<a>Dict</a> :: <a>Dict</a> (<a>Show</a> x)) (<a>Identity</a> a) yb -&gt; case yb of
--   &gt;           <a>Nothing</a> -&gt; <a>Const</a> (<a>show</a> a)
--   &gt;           <a>Just</a> b  -&gt; <a>Const</a> (<a>show</a> (a, b)) )
--   &gt;      foo1 foo2
--   &gt;   :: Foo (<a>Const</a> <a>String</a>)
--   Foo (<a>Const</a> "(0,1)") (<a>Const</a> "False")
--   </pre>
--   
--   Returns <a>Nothing</a> in case the indivual target types do not match.
--   
--   Note: <a>zip1</a> is safer but less general than <a>unsafeZip</a>.
zip1 :: (Monad m, Typeable f, Flayable1 c s, Flayable1 Typeable s) => (forall x. Dict (c x) -> f x -> g x -> m (h x)) -> s f -> s g -> m (Maybe (s h))

-- | Unsafe version of <a>zip</a> that doesn't guarantee that the given
--   <a>Flay</a>s target the same values. <a>zip</a> and <a>zip1</a> make
--   this function safe by simply using <a>flay</a> or <a>flay1</a> three
--   times.
--   
--   Returns <a>Nothing</a> in case the indivual target types do not match.
unsafeZip :: forall c s1 s2 t1 t2 t3 f g h m. (Monad m, Typeable f) => (Flay Typeable s1 t1 f (Const ())) -> (Flay Typeable s2 t2 g (Product f g)) -> (Flay c t2 t3 (Product f g) h) -> (forall x. Dict (c x) -> f x -> g x -> m (h x)) -> s1 -> s2 -> m (Maybe t3)
terminal :: Terminal a => a

-- | Witness that <tt>a</tt> is a terminal object. That is, that <tt>a</tt>
--   can always be constructed out of thin air.
class Terminal a
class GTerminal (f :: * -> *)

-- | Wrapper allowing a <a>Generic</a> non <a>Flayable</a> type to become
--   <a>Flayable</a>.
--   
--   Most datatypes that can have useful <a>Flayable</a> instances are
--   often parametrized by a type constructor <tt>f :: k -&gt; *</tt>, and
--   have all or some of their fields wrapped in said <tt>f</tt>, like so:
--   
--   <pre>
--   data Foo f = Foo (f <a>Int</a>) (f <a>Bool</a>)
--   </pre>
--   
--   However, that kind of representation is not that common, and it can
--   sometimes be unconfortable to use, particularly if <tt>f ~
--   <tt>Identity</tt></tt> due to the necessary wrapping and unwrapping of
--   values. In Haskell, it's more common to use a representation like the
--   following for records (or sums):
--   
--   <pre>
--   data Bar = Bar <a>Int</a> <a>Bool</a>
--     deriving (<a>Generic</a>)
--   </pre>
--   
--   The problem with that representation, however, is that it prevents us
--   to operate on the individual fields as enabled by <a>Flay</a>.
--   
--   <a>Pump</a> is a wrapper that converts types like <tt>Bar</tt> into
--   types like <tt>Foo</tt>. In our concrete case, <tt><a>Pump</a>
--   <tt>Bar</tt> f</tt> is isomorphic to <tt><tt>Foo</tt> f</tt>. But more
--   importantly, <tt><a>Pump</a> <tt>Bar</tt> f</tt> automatically gets a
--   <a>Flayable</a> instance of its own, allowing you to use <a>flay</a>
--   to operate on <tt><a>Pump</a> <tt>Bar</tt> f</tt> as you would operate
--   on <tt><tt>Foo</tt> f</tt>.
--   
--   To construct a <a>Pump</a> you use <a>pump</a>, and to remove the
--   <a>Pump</a> wrapper you use <a>dump</a>, which satisfy the following
--   identity law:
--   
--   <pre>
--   <a>dump</a> <a>id</a> . <a>pump</a> <a>pure</a>  ==  <a>pure</a>
--   </pre>
--   
--   <a>Pump</a> relies on Haskell's <a>Generic</a>s, which is why we
--   derived <a>Generic</a> for our <tt>Bar</tt> above. If <tt>Bar</tt>
--   didn't have a <a>Generic</a> instance, then you wouldn't be able to
--   use <a>Pump</a> and would be better served by a manually written
--   functions converting <tt>Bar</tt> to <tt>Foo</tt> and back.
--   
--   Keep in mind that <tt><a>Pump</a> s f</tt> will only add <tt>f</tt>
--   wrappers to the immediate children fields of <tt>s</tt> (which could
--   itself be a sum type or a product type), but it won't recurse into the
--   fields and add <tt>f</tt> wrappers to them.
--   
--   Very contrived and verbose example using all of <a>pump</a>,
--   <a>dump</a> and <a>flay</a>:
--   
--   <pre>
--   -- | Replaces all of the fields of the given Bar with values <a>Read</a> from
--   -- <a>stdin</a>, if possible.
--   qux :: Bar -&gt; <a>IO</a> (<a>Either</a> <a>String</a> <tt>Bar</tt>)
--   qux bar0 = do
--      let pbar0 :: <a>Pump</a> Bar <tt>Identity</tt>
--          pbar0 = <a>pump</a> <tt>Identity</tt> bar0
--      let h :: <a>Dict</a> (<a>Read</a> a) -&gt; <tt>Identity</tt> a -&gt; <a>IO</a> (<a>Maybe</a> a)
--          h <a>Dict</a> (<tt>Identity</tt> _) = <a>fmap</a> <a>readMaybe</a> <a>getLine</a>
--      pbar1 :: <a>Pump</a> Bar <a>Maybe</a> &lt;- <a>flay</a> h pbar0
--      -- We convert the <a>Maybe</a>s to <a>Either</a> just for demonstration purposes.
--      -- Using <a>dump</a> <a>id</a> would have been enough to make this function
--      -- return a <a>Maybe</a> Bar.
--      let ebar1 :: <a>Either</a> <a>String</a> <tt>Bar</tt>
--          ebar1 = <a>dump</a> (<a>maybe</a> (<a>Left</a> "Bad") <a>Right</a>) pbar1
--      pure ebar1
--   </pre>
--   
--   Or, written in a less verbose manner:
--   
--   <pre>
--   qux :: Bar -&gt; <a>IO</a> (<a>Either</a> <a>String</a> <tt>Bar</tt>)
--   qux bar = <a>fmap</a> (<a>dump</a> (<a>maybe</a> (<a>Left</a> "Bad") <a>Right</a>))
--                  (<a>flay</a> @<a>Read</a>
--                        ((<a>Dict</a> (<tt>Identity</tt> _) -&gt; <a>fmap</a> <a>readMaybe</a> <a>getLine</a>)
--                        (<a>pump</a> <tt>Identity</tt> bar)
--   </pre>
--   
--   We can use <tt>qux</tt> in GHCi as follows:
--   
--   <pre>
--   &gt; qux (Bar 0 False)
--   <i>not a number</i>
--   <i>not a bool</i>
--   <b>Left "Bad"</b>
--   
--   &gt; qux (Bar 0 False)
--   <i>1</i>
--   <i>True</i>
--   <b>Right (Bar 1 True)</b>
--   </pre>
data Pump s f

-- | Convenient <a>Constraint</a> for satisfying the requirements of
--   <a>pump</a> and <a>dump</a>.
type GPump s f = (Generic s, GPump' (Rep s) f)

-- | Wrap <tt>s</tt> in <a>Pump</a> so that it can be <a>flay</a>ed.
--   
--   See the documentation for <a>Pump</a> for more details.
pump :: GPump s f => (forall x. x -> f x) -> s -> Pump s f

-- | Remove the <a>Pump</a> wraper around <tt>s</tt>.
--   
--   See the documentation for <a>Pump</a> for more details.
dump :: (GPump s f, Applicative m) => (forall a. f a -> m a) -> Pump s f -> m s

-- | Ensure that all of the immeditate children fields of <tt>s</tt>
--   satisfy <tt>c</tt>.
--   
--   For example, in a datatype like the following:
--   
--   <pre>
--   data Bar = Bar <a>Int</a> <a>Bool</a>
--   </pre>
--   
--   The <a>Fields</a> constraint behaves like this:
--   
--   <pre>
--   <a>Fields</a> c Bar  ==  (c <a>Int</a>, c <a>Bool</a>)
--   </pre>
--   
--   <a>Fields</a> can be used to remove boilerplate from contexts, since
--   <tt>c</tt> will need to be mentioned just once, rather than once per
--   type of field. This is particularly useful in the case of datatypes as
--   <tt>Foo</tt> below, intended to be used with <a>Flay</a>:
--   
--   <pre>
--   data Foo f = Foo (f <a>Int</a>) (f <a>Bool</a>)
--   </pre>
--   
--   The problem with types shaped like <tt>Foo</tt> is that deriving some
--   useful instances for them, like <a>Show</a>, involves a lot of
--   boilerplate. For one, the usual <tt>deriving (<a>Show</a>)</tt>
--   statement doesn't work, and you need to rely on the
--   <tt>StandaloneDeriving</tt> GHC extension. But even that's not enough,
--   since you need to ensure that <a>Show</a> constrains the individual
--   field types as well. That is:
--   
--   <pre>
--   deriving instance (<a>Show</a> (f <a>Int</a>), <a>Show</a> (f <a>Bool</a>)) =&gt; <a>Show</a> (Foo f)
--   </pre>
--   
--   This works, but hopefully you can see how this can become very verbose
--   when you have more than a two or three datatypes in your fields.
--   Instead, provided we derive <a>Generic</a> for <tt>Foo</tt>, we can
--   use <a>Fields</a> to remove that boilerplate. That is:
--   
--   <pre>
--   data Foo f = Foo (f <a>Int</a>) (f <a>Bool</a>)
--     deriving (<a>Generic</a>)
--   
--   deriving instance <a>Fields</a> <a>Show</a> (Foo f) =&gt; <a>Show</a> (Foo f)
--   </pre>
type Fields c s = GFields c (Rep s)

-- | Like <a>Fields</a>, but <tt>s</tt> is expected to be a <a>Rep</a>.
--   
--   This <a>Constraint</a> ensures that <tt>c</tt> is satsfieds by all of
--   the <a>K1</a> types appearing in <tt>s</tt>, which is expected to be
--   one of the various <a>Generic</a> representation types.

-- | This is like <a>Fields</a>, but it targets only field types that are
--   wrapped by some type-constructor <tt>f</tt>.
--   
--   That is, for all <tt>a</tt> in <tt>s f</tt> such that <tt>f a</tt> is
--   an immediate children of <tt>s f</tt>, then <tt>c a</tt> must be
--   satisfied.
--   
--   <a>FieldsF</a> can be used to remove boilerplate from contexts, since
--   <tt>c</tt> will need to be mentioned just once, rather than once per
--   type of field. This is particularly useful in the case of datatypes as
--   <tt>Foo</tt> below, intended to be used with <a>Flay</a>:
--   
--   <pre>
--   data Foo f = Foo (f <a>Int</a>) (f <a>Bool</a>)
--   </pre>
--   
--   If, for example, you intend to implement a <tt><a>Flayable</a> c (Foo
--   f) (Foo g) f g</tt> instance, then constraints <tt>c <a>Int</a></tt>
--   and <tt>c <a>Bool</a></tt> will propagate. However, instead of writing
--   <tt>(c <a>Int</a>, c <a>Bool</a>)</tt>, you can write
--   <tt><a>FieldsF</a> c <tt>Foo</tt></tt> and achieve the same, which
--   will reduce boilerplate significantly in cases where the number of
--   types contained in <tt>f</tt> is larger. That is:
--   
--   <pre>
--   forall (c :: * -&gt; <a>Constraint</a>).
--      <a>FieldsF</a> c <tt>Foo</tt>  ==  (c <a>Int</a>, c <a>Bool</a>)
--   </pre>
--   
--   Notice that <a>FieldsF</a> only works with types of kind <tt>(k -&gt;
--   *) -&gt; *</tt> such as <tt>Foo</tt>. That is, types that are
--   parametrized by a type constructor.

-- | Like <a>FieldsF</a>, but <tt>s</tt> is expected to be a <a>Rep</a>,
--   and the type-constructor <tt>f</tt> expected to wrap all of the field
--   targets we want to constraint with <tt>c</tt> should be given
--   explicitly.
--   
--   This <a>Constraint</a> ensures that <tt>c</tt> is satsfieds by all of
--   the <a>K1</a> types appearing in <tt>s</tt> that are wrapped by
--   <tt>f</tt>.

-- | Values of type <tt><a>Dict</a> p</tt> capture a dictionary for a
--   constraint of type <tt>p</tt>.
--   
--   e.g.
--   
--   <pre>
--   <a>Dict</a> :: <a>Dict</a> (<a>Eq</a> <a>Int</a>)
--   </pre>
--   
--   captures a dictionary that proves we have an:
--   
--   <pre>
--   instance <a>Eq</a> 'Int
--   </pre>
--   
--   Pattern matching on the <a>Dict</a> constructor will bring this
--   instance into scope.
data Dict a
[Dict] :: Dict a
instance forall k (c :: k -> GHC.Types.Constraint) (r :: (k -> *) -> *). Flay.Flayable1K c r (Flay.Skolem (Flay.Flayable1K c r)) => Flay.Flayable1_ c r
instance forall k (c :: k -> GHC.Types.Constraint) (r :: (k -> *) -> *) x. Flay.Flayable c (r Flay.F) (r Flay.G) Flay.F Flay.G => Flay.Flayable1K c r x
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (r :: (k1 -> *) -> *). Flay.GFieldsF c (GHC.Generics.Rep (r Flay.F)) Flay.F => Flay.FieldsF_ c r
instance Flay.GFlay' c (Flay.GPumped (GHC.Generics.Rep s) f) (Flay.GPumped (GHC.Generics.Rep s) g) f g => Flay.Flayable c (Flay.Pump s f) (Flay.Pump s g) f g
instance Flay.GPump' GHC.Generics.V1 f
instance Flay.GPump' GHC.Generics.U1 f
instance Flay.GPump' (GHC.Generics.K1 i c) f
instance forall k (s :: k -> *) (f :: * -> *) i (j :: GHC.Generics.Meta). Flay.GPump' s f => Flay.GPump' (GHC.Generics.M1 i j s) f
instance forall k (sl :: k -> *) (f :: * -> *) (sr :: k -> *). (Flay.GPump' sl f, Flay.GPump' sr f) => Flay.GPump' (sl GHC.Generics.:*: sr) f
instance forall k (sl :: k -> *) (f :: * -> *) (sr :: k -> *). (Flay.GPump' sl f, Flay.GPump' sr f) => Flay.GPump' (sl GHC.Generics.:+: sr) f
instance (GHC.Generics.Generic a, Flay.GTerminal (GHC.Generics.Rep a)) => Flay.Terminal a
instance Flay.GTerminal GHC.Generics.U1
instance Flay.Terminal x => Flay.GTerminal (GHC.Generics.K1 i x)
instance Flay.GTerminal f => Flay.GTerminal (GHC.Generics.M1 i c f)
instance (Flay.GTerminal l, Flay.GTerminal r) => Flay.GTerminal (l GHC.Generics.:*: r)
instance Flay.Terminal ()
instance forall k (a :: k). Flay.Terminal (Data.Functor.Const.Const () a)
instance forall k (c :: k -> GHC.Types.Constraint) (r :: (k -> *) -> *) (f :: k -> *) (g :: k -> *). Flay.GFlay c (r f) (r g) f g => Flay.Flayable c (r f) (r g) f g
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (f :: k2 -> *) (g :: k2 -> *). Flay.GFlay' c GHC.Generics.V1 GHC.Generics.V1 f g
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (f :: k2 -> *) (g :: k2 -> *). Flay.GFlay' c GHC.Generics.U1 GHC.Generics.U1 f g
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (a :: k2) r (f :: k2 -> *) (g :: k2 -> *). c a => Flay.GFlay' c (GHC.Generics.K1 r (f a)) (GHC.Generics.K1 r (g a)) f g
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (s :: k1 -> *) (t :: k1 -> *) (f :: k2 -> *) (g :: k2 -> *) i (j :: GHC.Generics.Meta). Flay.GFlay' c s t f g => Flay.GFlay' c (GHC.Generics.M1 i j s) (GHC.Generics.M1 i j t) f g
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (sl :: k1 -> *) (tl :: k1 -> *) (f :: k2 -> *) (g :: k2 -> *) (sr :: k1 -> *) (tr :: k1 -> *). (Flay.GFlay' c sl tl f g, Flay.GFlay' c sr tr f g) => Flay.GFlay' c (sl GHC.Generics.:*: sr) (tl GHC.Generics.:*: tr) f g
instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (sl :: k1 -> *) (tl :: k1 -> *) (f :: k2 -> *) (g :: k2 -> *) (sr :: k1 -> *) (tr :: k1 -> *). (Flay.GFlay' c sl tl f g, Flay.GFlay' c sr tr f g) => Flay.GFlay' c (sl GHC.Generics.:+: sr) (tl GHC.Generics.:+: tr) f g
instance forall k (a :: k). Flay.Trivial a
