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


-- | Heterogeneous automatic differentation (backpropagation)
--   
--   Write your functions to compute your result, and the library will
--   automatically generate functions to compute your gradient.
--   
--   Implements heterogeneous reverse-mode automatic differentiation,
--   commonly known as "backpropagation".
--   
--   See <a>README.md</a>
@package backprop
@version 0.1.5.0


-- | Provides the <a>Op</a> type and combinators, which represent
--   differentiable functions/operations on values, and are used internally
--   by the library to perform back-propagation.
--   
--   Users of the library can ignore this module for the most part. Library
--   authors defining backpropagatable primitives for their functions are
--   recommend to simply use <a>op0</a>, <a>op1</a>, <a>op2</a>,
--   <a>op3</a>, which are re-exported in <a>Numeric.Backprop</a>. However,
--   authors who want more options in defining their primtive functions
--   might find some of these functions useful.
--   
--   Note that if your entire function is a single non-branching
--   composition of functions, <a>Op</a> and its utility functions alone
--   are sufficient to differentiate/backprop. However, this happens rarely
--   in practice.
module Numeric.Backprop.Op

-- | An <tt><a>Op</a> as a</tt> describes a differentiable function from
--   <tt>as</tt> to <tt>a</tt>.
--   
--   For example, a value of type
--   
--   <pre>
--   <a>Op</a> '[Int, Bool] Double
--   </pre>
--   
--   is a function from an <a>Int</a> and a <a>Bool</a>, returning a
--   <a>Double</a>. It can be differentiated to give a <i>gradient</i> of
--   an <a>Int</a> and a <a>Bool</a> if given a total derivative for the
--   <tt>Double</tt>. If we call <a>Bool</a> &lt;math&gt;, then,
--   mathematically, it is akin to a:
--   
--   &lt;math&gt;
--   
--   See <a>runOp</a>, <a>gradOp</a>, and <a>gradOpWith</a> for examples on
--   how to run it, and <a>Op</a> for instructions on creating it.
--   
--   It is simpler to not use this type constructor directly, and instead
--   use the <a>op2</a>, <a>op1</a>, <a>op2</a>, and <a>op3</a> helper
--   smart constructors.
--   
--   See <a>Numeric.Backprop.Op#prod</a> for a mini-tutorial on using
--   <a>Prod</a> and <a>Tuple</a>.
newtype Op as a

-- | Construct an <a>Op</a> by giving a function creating the result, and
--   also a continuation on how to create the gradient, given the total
--   derivative of <tt>a</tt>.
--   
--   See the module documentation for <a>Numeric.Backprop.Op</a> for more
--   details on the function that this constructor and <a>Op</a> expect.
Op :: (Tuple as -> (a, a -> Tuple as)) -> Op as a

-- | Run the function that the <a>Op</a> encodes, returning a continuation
--   to compute the gradient, given the total derivative of <tt>a</tt>. See
--   documentation for <a>Numeric.Backprop.Op</a> for more information.
[runOpWith] :: Op as a -> Tuple as -> (a, a -> Tuple as)
data Prod k (f :: k -> *) (a :: [k]) :: forall k. () => (k -> *) -> [k] -> *
[Ø] :: Prod k f [] k
[:<] :: Prod k f (:) k a1 as

-- | A Prod of simple Haskell types.
type Tuple = Prod * I
newtype I a :: * -> *
I :: a -> I a
[getI] :: I a -> a

-- | Run the function that an <a>Op</a> encodes, to get the resulting
--   output and also its gradient with respect to the inputs.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' (op2 (*)) (3 ::&lt; 5 ::&lt; Ø)
--   (15, 5 ::&lt; 3 ::&lt; Ø)
--   </pre>
runOp :: Num a => Op as a -> Tuple as -> (a, Tuple as)

-- | Run the function that an <a>Op</a> encodes, to get the result.
--   
--   <pre>
--   &gt;&gt;&gt; runOp (op2 (*)) (3 ::&lt; 5 ::&lt; Ø)
--   15
--   </pre>
evalOp :: Op as a -> Tuple as -> a

-- | Run the function that an <a>Op</a> encodes, and get the gradient of
--   the output with respect to the inputs.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp (op2 (*)) (3 ::&lt; 5 ::&lt; Ø)
--   5 ::&lt; 3 ::&lt; Ø
--   -- the gradient of x*y is (y, x)
--   </pre>
--   
--   <pre>
--   <a>gradOp</a> o xs = <a>gradOpWith</a> o xs 1
--   </pre>
gradOp :: Num a => Op as a -> Tuple as -> Tuple as

-- | Get the gradient function that an <a>Op</a> encodes, with a third
--   argument expecting the total derivative of the result.
--   
--   See the module documentaiton for <a>Numeric.Backprop.Op</a> for more
--   information.
gradOpWith :: Op as a -> Tuple as -> a -> Tuple as

-- | Create an <a>Op</a> that takes no inputs and always returns the given
--   value.
--   
--   There is no gradient, of course (using <a>gradOp</a> will give you an
--   empty tuple), because there is no input to have a gradient of.
--   
--   <pre>
--   &gt;&gt;&gt; runOp (op0 10) Ø
--   (10, Ø)
--   </pre>
--   
--   For a constant <a>Op</a> that takes input and ignores it, see
--   <a>opConst</a> and <a>opConst'</a>.
op0 :: a -> Op '[] a

-- | An <a>Op</a> that ignores all of its inputs and returns a given
--   constant value.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' (opConst 10) (1 ::&lt; 2 ::&lt; 3 ::&lt; Ø)
--   (10, 0 ::&lt; 0 ::&lt; 0 ::&lt; Ø)
--   </pre>
opConst :: (Every Num as, Known Length as) => a -> Op as a

-- | An <a>Op</a> that just returns whatever it receives. The identity
--   function.
--   
--   <pre>
--   <a>idOp</a> = <a>opIso</a> <a>id</a> <a>id</a>
--   </pre>
idOp :: Op '[a] a

-- | A version of <a>opConst</a> taking explicit <a>Length</a>, indicating
--   the number of inputs and their types.
--   
--   Requiring an explicit <a>Length</a> is mostly useful for rare
--   "extremely polymorphic" situations, where GHC can't infer the type and
--   length of the the expected input tuple. If you ever actually
--   explicitly write down <tt>as</tt> as a list of types, you should be
--   able to just use <a>opConst</a>.
opConst' :: Every Num as => Length as -> a -> Op as a

-- | An <a>Op</a> that extracts a value from an input value using a
--   <a>Lens'</a>.
--   
--   Warning: This is unsafe! It assumes that it extracts a specific value
--   unchanged, with derivative 1, so will break for things that
--   numerically manipulate things before returning them.
opLens :: Num a => Lens' a b -> Op '[a] b

-- | Create an <a>Op</a> of a function taking one input, by giving its
--   explicit derivative. The function should return a tuple containing the
--   result of the function, and also a function taking the derivative of
--   the result and return the derivative of the input.
--   
--   If we have
--   
--   &lt;math&gt;
--   
--   Then the derivative &lt;math&gt;, it would be:
--   
--   &lt;math&gt;
--   
--   If our <a>Op</a> represents &lt;math&gt;, then the second item in the
--   resulting tuple should be a function that takes &lt;math&gt; and
--   returns &lt;math&gt;.
--   
--   As an example, here is an <a>Op</a> that squares its input:
--   
--   <pre>
--   square :: Num a =&gt; <a>Op</a> '[a] a
--   square = <a>op1</a> $ \x -&gt; (x*x, \d -&gt; 2 * d * x
--                        )
--   </pre>
--   
--   Remember that, generally, end users shouldn't directly construct
--   <a>Op</a>s; they should be provided by libraries or generated
--   automatically.
op1 :: (a -> (b, b -> a)) -> Op '[a] b

-- | Create an <a>Op</a> of a function taking two inputs, by giving its
--   explicit gradient. The function should return a tuple containing the
--   result of the function, and also a function taking the derivative of
--   the result and return the derivative of the input.
--   
--   If we have
--   
--   &lt;math&gt;
--   
--   Then the gradient &lt;math&gt; would be:
--   
--   &lt;math&gt;
--   
--   If our <a>Op</a> represents &lt;math&gt;, then the second item in the
--   resulting tuple should be a function that takes &lt;math&gt; and
--   returns &lt;math&gt;.
--   
--   As an example, here is an <a>Op</a> that multiplies its inputs:
--   
--   <pre>
--   mul :: Num a =&gt; <a>Op</a> '[a, a] a
--   mul = <tt>op2'</tt> $ \x y -&gt; (x*y, \d -&gt; (d*y, x*d)
--                        )
--   </pre>
--   
--   Remember that, generally, end users shouldn't directly construct
--   <a>Op</a>s; they should be provided by libraries or generated
--   automatically.
op2 :: (a -> b -> (c, c -> (a, b))) -> Op '[a, b] c

-- | Create an <a>Op</a> of a function taking three inputs, by giving its
--   explicit gradient. See documentation for <a>op2</a> for more details.
op3 :: (a -> b -> c -> (d, d -> (a, b, c))) -> Op '[a, b, c] d

-- | An <a>Op</a> that coerces an item into another item whose type has the
--   same runtime representation.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' opCoerce (Identity 5) :: (Int, Identity Int)
--   (5, Identity 1)
--   </pre>
--   
--   <pre>
--   <a>opCoerce</a> = <a>opIso</a> <tt>coerced</tt> <a>coerce</a>
--   </pre>
opCoerce :: Coercible a b => Op '[a] b

-- | An <a>Op</a> that takes <tt>as</tt> and returns exactly the input
--   tuple.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' opTup (1 ::&lt; 2 ::&lt; 3 ::&lt; Ø)
--   (1 ::&lt; 2 ::&lt; 3 ::&lt; Ø, 1 ::&lt; 1 ::&lt; 1 ::&lt; Ø)
--   </pre>
opTup :: Op as (Tuple as)

-- | An <a>Op</a> that runs the input value through an isomorphism.
--   
--   Warning: This is unsafe! It assumes that the isomorphisms themselves
--   have derivative 1, so will break for things like <a>exp</a> &amp;
--   <a>log</a>. Basically, don't use this for any "numeric" isomorphisms.
opIso :: (a -> b) -> (b -> a) -> Op '[a] b

-- | An <a>Op</a> that runs the two input values through an isomorphism.
--   Useful for things like constructors. See <a>opIso</a> for caveats.
opIso2 :: (a -> b -> c) -> (c -> (a, b)) -> Op '[a, b] c

-- | An <a>Op</a> that runs the three input values through an isomorphism.
--   Useful for things like constructors. See <a>opIso</a> for caveats.
opIso3 :: (a -> b -> c -> d) -> (d -> (a, b, c)) -> Op '[a, b, c] d

-- | An <a>Op</a> that runs the input value through an isomorphism between
--   a tuple of values and a value. See <a>opIso</a> for caveats.
--   
--   In <a>Numeric.Backprop.Op</a> since version 0.1.2.0, but only exported
--   from <a>Numeric.Backprop</a> since version 0.1.3.0.
opIsoN :: (Tuple as -> b) -> (b -> Tuple as) -> Op as b

-- | Create an <a>Op</a> with no gradient. Can be evaluated with
--   <a>evalOp</a>, but will throw a runtime exception when asked for the
--   gradient.
--   
--   Can be used with <tt>BVar</tt> with <tt>liftOp1</tt>, and
--   <tt>evalBP</tt> will work fine. <tt>gradBP</tt> and <tt>backprop</tt>
--   will also work fine if the result is never used in the final answer,
--   but will throw a runtime exception if the final answer depends on the
--   result of this operation.
--   
--   Useful if your only API is exposed through <i>backprop</i>. Just be
--   sure to tell your users that this will explode when finding the
--   gradient if the result is used in the final result.
noGrad1 :: (a -> b) -> Op '[a] b

-- | Create an <a>Op</a> with no gradient. Can be evaluated with
--   <a>evalOp</a>, but will throw a runtime exception when asked for the
--   gradient.
--   
--   Can be used with <tt>BVar</tt> with <tt>liftOp</tt>, and
--   <tt>evalBP</tt> will work fine. <tt>gradBP</tt> and <tt>backprop</tt>
--   will also work fine if the result is never used in the final answer,
--   but will throw a runtime exception if the final answer depends on the
--   result of this operation.
--   
--   Useful if your only API is exposed through <i>backprop</i>. Just be
--   sure to tell your users that this will explode when finding the
--   gradient if the result is used in the final result.
noGrad :: (Tuple as -> b) -> Op as b

-- | Compose <a>Op</a>s together, like <a>sequence</a> for functions, or
--   <tt>liftAN</tt>.
--   
--   That is, given an <tt><a>Op</a> as b1</tt>, an <tt><a>Op</a> as
--   b2</tt>, and an <tt><a>Op</a> as b3</tt>, it can compose them with an
--   <tt><a>Op</a> '[b1,b2,b3] c</tt> to create an <tt><a>Op</a> as c</tt>.
composeOp :: (Every Num as, Known Length as) => Prod (Op as) bs -> Op bs c -> Op as c

-- | Convenient wrapper over <a>composeOp</a> for the case where the second
--   function only takes one input, so the two <a>Op</a>s can be directly
--   piped together, like for <a>.</a>.
composeOp1 :: (Every Num as, Known Length as) => Op as b -> Op '[b] c -> Op as c

-- | Convenient infix synonym for (flipped) <a>composeOp1</a>. Meant to be
--   used just like <a>.</a>:
--   
--   <pre>
--   f :: <a>Op</a> '[b]   c
--   g :: <a>Op</a> '[a,a] b
--   
--   f <a>~.</a> g :: Op '[a, a] c
--   </pre>
(~.) :: (Known Length as, Every Num as) => Op '[b] c -> Op as b -> Op as c
infixr 9 ~.

-- | A version of <a>composeOp</a> taking explicit <a>Length</a>,
--   indicating the number of inputs expected and their types.
--   
--   Requiring an explicit <a>Length</a> is mostly useful for rare
--   "extremely polymorphic" situations, where GHC can't infer the type and
--   length of the the expected input tuple. If you ever actually
--   explicitly write down <tt>as</tt> as a list of types, you should be
--   able to just use <a>composeOp</a>.
composeOp' :: Every Num as => Length as -> Prod (Op as) bs -> Op bs c -> Op as c

-- | A version of <a>composeOp1</a> taking explicit <a>Length</a>,
--   indicating the number of inputs expected and their types.
--   
--   Requiring an explicit <a>Length</a> is mostly useful for rare
--   "extremely polymorphic" situations, where GHC can't infer the type and
--   length of the the expected input tuple. If you ever actually
--   explicitly write down <tt>as</tt> as a list of types, you should be
--   able to just use <a>composeOp1</a>.
composeOp1' :: Every Num as => Length as -> Op as b -> Op '[b] c -> Op as c

-- | Construct a two element Prod. Since the precedence of (:&gt;) is
--   higher than (:&lt;), we can conveniently write lists like:
--   
--   <pre>
--   &gt;&gt;&gt; a :&lt; b :&gt; c
--   </pre>
--   
--   Which is identical to:
--   
--   <pre>
--   &gt;&gt;&gt; a :&lt; b :&lt; c :&lt; Ø
--   </pre>
infix 6 :>

-- | Build a singleton Prod.
only :: () => f a -> Prod k f (:) k a [] k
head' :: () => Prod k f (:<) k a as -> f a

-- | Cons onto a Tuple.
infixr 5 ::<

-- | Singleton Tuple.
only_ :: () => a -> Tuple (:) * a [] *

-- | <a>Op</a> for addition
(+.) :: Num a => Op '[a, a] a

-- | <a>Op</a> for subtraction
(-.) :: Num a => Op '[a, a] a

-- | <a>Op</a> for multiplication
(*.) :: Num a => Op '[a, a] a

-- | <a>Op</a> for negation
negateOp :: Num a => Op '[a] a

-- | <a>Op</a> for absolute value
absOp :: Num a => Op '[a] a

-- | <a>Op</a> for <a>signum</a>
signumOp :: Num a => Op '[a] a

-- | <a>Op</a> for division
(/.) :: Fractional a => Op '[a, a] a

-- | <a>Op</a> for multiplicative inverse
recipOp :: Fractional a => Op '[a] a

-- | <a>Op</a> for <a>exp</a>
expOp :: Floating a => Op '[a] a

-- | <a>Op</a> for the natural logarithm
logOp :: Floating a => Op '[a] a

-- | <a>Op</a> for square root
sqrtOp :: Floating a => Op '[a] a

-- | <a>Op</a> for exponentiation
(**.) :: Floating a => Op '[a, a] a

-- | <a>Op</a> for <a>logBase</a>
logBaseOp :: Floating a => Op '[a, a] a

-- | <a>Op</a> for sine
sinOp :: Floating a => Op '[a] a

-- | <a>Op</a> for cosine
cosOp :: Floating a => Op '[a] a

-- | <a>Op</a> for tangent
tanOp :: Floating a => Op '[a] a

-- | <a>Op</a> for arcsine
asinOp :: Floating a => Op '[a] a

-- | <a>Op</a> for arccosine
acosOp :: Floating a => Op '[a] a

-- | <a>Op</a> for arctangent
atanOp :: Floating a => Op '[a] a

-- | <a>Op</a> for hyperbolic sine
sinhOp :: Floating a => Op '[a] a

-- | <a>Op</a> for hyperbolic cosine
coshOp :: Floating a => Op '[a] a

-- | <a>Op</a> for hyperbolic tangent
tanhOp :: Floating a => Op '[a] a

-- | <a>Op</a> for hyperbolic arcsine
asinhOp :: Floating a => Op '[a] a

-- | <a>Op</a> for hyperbolic arccosine
acoshOp :: Floating a => Op '[a] a

-- | <a>Op</a> for hyperbolic arctangent
atanhOp :: Floating a => Op '[a] a
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Data.Type.Index.Every * GHC.Num.Num as, GHC.Num.Num a) => GHC.Num.Num (Numeric.Backprop.Op.Op as a)
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Data.Type.Index.Every * GHC.Real.Fractional as, Data.Type.Index.Every * GHC.Num.Num as, GHC.Real.Fractional a) => GHC.Real.Fractional (Numeric.Backprop.Op.Op as a)
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Data.Type.Index.Every * GHC.Float.Floating as, Data.Type.Index.Every * GHC.Real.Fractional as, Data.Type.Index.Every * GHC.Num.Num as, GHC.Float.Floating a) => GHC.Float.Floating (Numeric.Backprop.Op.Op as a)


-- | Automatic differentation and backpropagation.
--   
--   Main idea: Write a function computing what you want, and the library
--   automatically provies the gradient of that function as well, for usage
--   with gradient descent and other training methods.
--   
--   In more detail: instead of working directly with values to produce
--   your result, you work with <a>BVar</a>s containing those values.
--   Working with these <a>BVar</a>s is made smooth with the usage of
--   lenses and other combinators, and libraries can offer operatons on
--   <a>BVar</a>s instead of those on normal types directly.
--   
--   Then, you can use:
--   
--   <pre>
--   <a>evalBP</a> :: (forall s. <a>Reifies</a> s <a>W</a>. <a>BVar</a> s a -&gt; BVar s b) -&gt; (a -&gt; b)
--   </pre>
--   
--   to turn a <a>BVar</a> function into the function on actual values
--   <tt>a -&gt; b</tt>. This has virtually zero overhead over writing the
--   actual function directly.
--   
--   Then, there's:
--   
--   <pre>
--   <a>gradBP</a> :: (forall s. <a>Reifies</a> s <a>W</a>. <a>BVar</a> s a -&gt; BVar s b) -&gt; (a -&gt; a)
--   </pre>
--   
--   to automatically get the <i>gradient</i>, as well, for a given input.
--   
--   See the <a>README</a> for more information and links to demonstrations
--   and tutorials, or dive striaght in by reading the docs for
--   <a>BVar</a>.
module Numeric.Backprop

-- | A <tt><a>BVar</a> s a</tt> is a value of type <tt>a</tt> that can be
--   "backpropagated".
--   
--   Functions referring to <a>BVar</a>s are tracked by the library and can
--   be automatically differentiated to get their gradients and results.
--   
--   For simple numeric values, you can use its <a>Num</a>,
--   <a>Fractional</a>, and <a>Floating</a> instances to manipulate them as
--   if they were the numbers they represent.
--   
--   If <tt>a</tt> contains items, the items can be accessed and extracted
--   using lenses. A <tt><a>Lens'</a> b a</tt> can be used to access an
--   <tt>a</tt> inside a <tt>b</tt>, using <tt>^^.</tt> (<a>viewVar</a>):
--   
--   <pre>
--   (<a>^.</a>)  ::        a -&gt; <a>Lens'</a> a b -&gt;        b
--   (<tt>^^.</tt>) :: <a>BVar</a> s a -&gt; <a>Lens'</a> a b -&gt; <a>BVar</a> s b
--   </pre>
--   
--   There is also <tt>^^?</tt> (<a>previewVar</a>), to use a
--   <tt>Prism'</tt> or <a>Traversal'</a> to extract a target that may or
--   may not be present (which can implement pattern matching),
--   <tt>^^..</tt> (<a>toListOfVar</a>) to use a <a>Traversal'</a> to
--   extract <i>all</i> targets inside a <a>BVar</a>, and <tt>.~~</tt>
--   (<a>setVar</a>) to set and update values inside a <a>BVar</a>.
--   
--   For more complex operations, libraries can provide functions on
--   <a>BVar</a>s using <a>liftOp</a> and related functions. This is how
--   you can create primitive functions that users can use to manipulate
--   your library's values.
--   
--   For example, the <i>hmatrix</i> library has a matrix-vector
--   multiplication function, <tt>#&gt; :: L m n -&gt; R n -&gt; L m</tt>.
--   
--   A library could instead provide a function <tt>#&gt; :: <a>BVar</a> (L
--   m n) -&gt; BVar (R n) -&gt; BVar (R m)</tt>, which the user can then
--   use to manipulate their <a>BVar</a>s of <tt>L m n</tt>s and <tt>R
--   n</tt>s, etc.
--   
--   See <a>Numeric.Backprop#liftops</a> and documentation for
--   <a>liftOp</a> for more information.
data BVar s a

-- | An ephemeral Wengert Tape in the environment. Used internally to track
--   of the computational graph of variables.
--   
--   For the end user, one can just imagine <tt><a>Reifies</a> s
--   <a>W</a></tt> as a required constraint on <tt>s</tt> that allows
--   backpropagation to work.
data W

-- | Turn a function <tt><a>BVar</a> s a -&gt; <a>BVar</a> s b</tt> into
--   the function <tt>a -&gt; b</tt> that it represents, also computing its
--   gradient <tt>a</tt> as well.
--   
--   The Rank-N type <tt>forall s. <a>Reifies</a> s <a>W</a> =&gt; ...</tt>
--   is used to ensure that <a>BVar</a>s do not leak out of the context
--   (similar to how it is used in <a>Control.Monad.ST</a>), and also as a
--   reference to an ephemeral Wengert tape used to track the graph of
--   references.
--   
--   Note that every type involved has to be an instance of <a>Num</a>.
--   This is because gradients all need to be "summable" (which is
--   implemented using <a>sum</a> and <a>+</a>), and we also need to able
--   to generate gradients of 1 and 0. Really, only <a>+</a> and
--   <a>fromInteger</a> methods are used from the <a>Num</a> typeclass.
--   
--   This might change in the future, to allow easier integration with
--   tuples (which typically do not have a <a>Num</a> instance), and
--   potentially make types easier to use (by only requiring <a>+</a>, 0,
--   and 1, and not the rest of the <a>Num</a> class).
--   
--   See the <a>README</a> for a more detailed discussion on this issue.
--   
--   If you need a <a>Num</a> instance for tuples, you can use the
--   canonical 2- and 3-tuples for the library in
--   <a>Numeric.Backprop.Tuple</a>. If you need one for larger tuples,
--   consider making a custom product type instead (making Num instances
--   with something like <a>one-liner-instances</a>). You can also use the
--   orphan instances in the <a>NumInstances</a> package (in particular,
--   <a>Data.NumInstances.Tuple</a>) if you are writing an application and
--   do not have to worry about orphan instances.
backprop :: forall a b. (Num a, Num b) => (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> (b, a)

-- | Turn a function <tt><a>BVar</a> s a -&gt; <a>BVar</a> s b</tt> into
--   the function <tt>a -&gt; b</tt> that it represents.
--   
--   Benchmarks show that this should have virtually no overhead over
--   directly writing a <tt>a -&gt; b</tt>. <a>BVar</a> is, in this
--   situation, a zero-cost abstraction, performance-wise.
--   
--   Has a nice advantage over using <a>backprop</a> in that it doesn't
--   require <a>Num</a> constraints on the input and output.
--   
--   See documentation of <a>backprop</a> for more information.
evalBP :: (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> b

-- | Take a function <tt><a>BVar</a> s a -&gt; <a>BVar</a> s b</tt>,
--   interpreted as a function <tt>a -&gt; b</tt>, and compute its gradient
--   with respect to its input.
--   
--   The resulting <tt>a -&gt; a</tt> tells how the input (and its
--   components) affects the output. Positive numbers indicate that the
--   result will vary in the same direction as any adjustment in the input.
--   Negative numbers indicate that the result will vary in the opposite
--   direction as any adjustment in the input. Larger numbers indicate a
--   greater sensitivity of change, and small numbers indicate lower
--   sensitivity.
--   
--   See documentation of <a>backprop</a> for more information.
gradBP :: forall a b. (Num a, Num b) => (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> a

-- | <a>backprop</a> for a two-argument function.
--   
--   Not strictly necessary, because you can always uncurry a function by
--   passing in all of the argument inside a data type, or use <tt>T2</tt>.
--   However, this could potentially be more performant.
--   
--   For 3 and more arguments, consider using <a>backpropN</a>.
backprop2 :: forall a b c. (Num a, Num b, Num c) => (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (c, (a, b))

-- | <a>evalBP</a> for a two-argument function. See <a>backprop2</a> for
--   notes.
evalBP2 :: (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> c

-- | <a>gradBP</a> for a two-argument function. See <a>backprop2</a> for
--   notes.
gradBP2 :: (Num a, Num b, Num c) => (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (a, b)

-- | <tt>backprop</tt> generalized to multiple inputs of different types.
--   See the <a>Numeric.Backprop.Op#prod</a> for a mini-tutorial on
--   heterogeneous lists.
--   
--   Not strictly necessary, because you can always uncurry a function by
--   passing in all of the inputs in a data type containing all of the
--   arguments or a tuple from <a>Numeric.Backprop.Tuple</a>. You could
--   also pass in a giant tuple with <a>NumInstances</a>. However, this can
--   be convenient if you don't want to make a custom larger tuple type or
--   pull in orphan instances. This could potentially also be more
--   performant.
--   
--   A <tt><a>Prod</a> (<a>BVar</a> s) '[Double, Float, Double]</tt>, for
--   instance, is a tuple of <tt><a>BVar</a> s <a>Double</a></tt>,
--   <tt><a>BVar</a> s <a>Float</a></tt>, and <tt><a>BVar</a> s
--   <a>Double</a></tt>, and can be pattern matched on using <a>:&lt;</a>
--   (cons) and 'Ø' (nil).
--   
--   Tuples can be built and pattern matched on using <a>::&lt;</a> (cons)
--   and 'Ø' (nil), as well.
--   
--   The <tt><a>Every</a> <a>Num</a> as</tt> in the constraint says that
--   every value in the type-level list <tt>as</tt> must have a <a>Num</a>
--   instance. This means you can use, say, <tt>'[Double, Float, Int]</tt>,
--   but not <tt>'[Double, Bool, String]</tt>.
--   
--   If you stick to <i>concerete</i>, monomorphic usage of this (with
--   specific types, typed into source code, known at compile-time), then
--   <tt><a>Every</a> <a>Num</a> as</tt> should be fulfilled automatically.
backpropN :: forall as b. (Every Num as, Num b) => (forall s. Reifies s W => Prod (BVar s) as -> BVar s b) -> Tuple as -> (b, Tuple as)

-- | <tt>evalBP</tt> generalized to multiple inputs of different types. See
--   documentation for <a>backpropN</a> for more details.
evalBPN :: forall as b. () => (forall s. Reifies s W => Prod (BVar s) as -> BVar s b) -> Tuple as -> b

-- | <a>gradBP</a> generalized to multiple inputs of different types. See
--   documentation for <a>backpropN</a> for more details.
gradBPN :: forall as b. (Every Num as, Num b) => (forall s. Reifies s W => Prod (BVar s) as -> BVar s b) -> Tuple as -> Tuple as
class EveryC k c as => Every k (c :: k -> Constraint) (as :: [k])

-- | Lift a value into a <a>BVar</a> representing a constant value.
--   
--   This value will not be considered an input, and its gradients will not
--   be backpropagated.
constVar :: a -> BVar s a

-- | An infix version of <a>viewVar</a>, meant to evoke parallels to
--   <a>^.</a> from lens.
--   
--   With normal values, you can extract something from that value with a
--   lens:
--   
--   <pre>
--   x <a>^.</a> myLens
--   </pre>
--   
--   would extract a piece of <tt>x :: b</tt>, specified by <tt>myLens ::
--   <a>Lens'</a> b a</tt>. The result has type <tt>a</tt>.
--   
--   <pre>
--   xVar <a>^^.</a> myLens
--   </pre>
--   
--   would extract a piece out of <tt>xVar :: <a>BVar</a> s b</tt> (a
--   <a>BVar</a> holding a <tt>b</tt>), specified by <tt>myLens :: Lens' b
--   a</tt>. The result has type <tt><a>BVar</a> s a</tt> (a <a>BVar</a>
--   holding a <tt>a</tt>)
--   
--   This is the main way to pull out values from <a>BVar</a> of container
--   types.
--   
--   <b>WARNING</b>: Do not use with any lenses that operate "numerically"
--   on the contents (like <tt>multiplying</tt>).
(^^.) :: forall a b s. (Reifies s W, Num a) => BVar s b -> Lens' b a -> BVar s a
infixl 8 ^^.

-- | An infix version of <a>setVar</a>, meant to evoke parallels to
--   <a>.~</a> from lens.
--   
--   With normal values, you can set something in a value with a lens: a
--   lens:
--   
--   <pre>
--   x <a>&amp;</a> myLens <a>.~</a> <tt>y</tt>
--   </pre>
--   
--   would "set" a part of <tt>x :: b</tt>, specified by <tt>myLens ::
--   <a>Lens'</a> a b</tt>, to a new value <tt>y :: a</tt>.
--   
--   <pre>
--   xVar <a>&amp;</a> myLens <a>.~~</a> yVar
--   </pre>
--   
--   would "set" a part of <tt>xVar :: <a>BVar</a> s b</tt> (a <a>BVar</a>
--   holding a <tt>b</tt>), specified by <tt>myLens :: <a>Lens'</a> a
--   b</tt>, to a new value given by <tt>yVar :: <a>BVar</a> s a</tt>. The
--   result is a new (updated) value of type <tt><a>BVar</a> s b</tt>.
--   
--   This is the main way to set values inside <a>BVar</a>s of container
--   types.
(.~~) :: forall a b s. (Reifies s W, Num a, Num b) => Lens' b a -> BVar s a -> BVar s b -> BVar s b
infixl 8 .~~

-- | An infix version of <a>previewVar</a>, meant to evoke parallels to
--   <a>^?</a> from lens.
--   
--   With normal values, you can (potentially) extract something from that
--   value with a lens:
--   
--   <pre>
--   x <a>^?</a> myPrism
--   </pre>
--   
--   would (potentially) extract a piece of <tt>x :: b</tt>, specified by
--   <tt>myPrism :: <a>Traversal'</a> b a</tt>. The result has type
--   <tt><a>Maybe</a> a</tt>.
--   
--   <pre>
--   xVar <a>^^?</a> myPrism
--   </pre>
--   
--   would (potentially) extract a piece out of <tt>xVar :: <a>BVar</a> s
--   b</tt> (a <a>BVar</a> holding a <tt>b</tt>), specified by <tt>myPrism
--   :: Prism' b a</tt>. The result has type <tt><a>Maybe</a> (<a>BVar</a>
--   s a)</tt> (<a>Maybe</a> a <a>BVar</a> holding a <tt>a</tt>).
--   
--   This is intended to be used with <tt>Prism'</tt>s (which hits at most
--   one target), but will actually work with <i>any</i> <a>Traversal'</a>.
--   If the traversal hits more than one target, the first one found will
--   be extracted.
--   
--   This can be used to "pattern match" on <a>BVar</a>s, by using prisms
--   on constructors.
--   
--   Note that many automatically-generated prisms by the <i>lens</i>
--   package use tuples, which cannot normally be backpropagated (because
--   they do not have a <a>Num</a> instance).
--   
--   If you are writing an application or don't have to worry about orphan
--   instances, you can pull in the orphan instances from
--   <a>NumInstances</a>. Alternatively, you can chain those prisms with
--   conversions to the anonymous canonical strict tuple types in
--   <a>Numeric.Backprop.Tuple</a>, which do have <a>Num</a> instances.
--   
--   <pre>
--   myPrism                   :: <tt>Prism'</tt> c (a, b)
--   myPrism . <tt>iso</tt> <tt>tupT2</tt> <tt>t2Tup</tt> :: <tt>Prism'</tt> c (<tt>T2</tt> a b)
--   </pre>
(^^?) :: forall b a s. (Num a, Reifies s W) => BVar s b -> Traversal' b a -> Maybe (BVar s a)

-- | An infix version of <a>toListOfVar</a>, meant to evoke parallels to
--   <a>^..</a> from lens.
--   
--   With normal values, you can extract all targets of a <a>Traversal</a>
--   from that value with a:
--   
--   <pre>
--   x <a>^..</a> myTraversal
--   </pre>
--   
--   would extract all targets inside of <tt>x :: b</tt>, specified by
--   <tt>myTraversal :: <a>Traversal'</a> b a</tt>. The result has type
--   <tt>[a]</tt>.
--   
--   <pre>
--   xVar <a>^^..</a> myTraversal
--   </pre>
--   
--   would extract all targets inside of <tt>xVar :: <a>BVar</a> s b</tt>
--   (a <a>BVar</a> holding a <tt>b</tt>), specified by <tt>myTraversal ::
--   Traversal' b a</tt>. The result has type <tt>[<a>BVar</a> s a]</tt> (A
--   list of <a>BVar</a>s holding <tt>a</tt>s).
(^^..) :: forall b a s. (Num a, Reifies s W) => BVar s b -> Traversal' b a -> [BVar s a]

-- | Using a <a>Lens'</a>, extract a value <i>inside</i> a <a>BVar</a>.
--   Meant to evoke parallels to <tt>view</tt> from lens.
--   
--   See documentation for <tt>^^.</tt> for more information.
viewVar :: forall a b s. (Reifies s W, Num a) => Lens' b a -> BVar s b -> BVar s a

-- | Using a <a>Lens'</a>, set a value <i>inside</i> a <a>BVar</a>. Meant
--   to evoke parallels to "set" from lens.
--   
--   See documentation for <tt>.~~</tt> for more information.
setVar :: forall a b s. (Reifies s W, Num a, Num b) => Lens' b a -> BVar s a -> BVar s b -> BVar s b

-- | Extract all of the <a>BVar</a>s out of a <a>Traversable</a> container
--   of <a>BVar</a>s.
--   
--   Note that this associates gradients in order of occurrence in the
--   original data structure; the second item in the gradient is assumed to
--   correspond with the second item in the input, etc.; this can cause
--   unexpected behavior in <a>Foldable</a> instances that don't have a
--   fixed number of items.
sequenceVar :: forall t a s. (Reifies s W, Traversable t, Num a) => BVar s (t a) -> t (BVar s a)

-- | Collect all of the <a>BVar</a>s in a container into a <a>BVar</a> of
--   that container's contents.
--   
--   Note that this associates gradients in order of occurrence in the
--   original data structure; the second item in the total derivative and
--   gradient is assumed to correspond with the second item in the input,
--   etc.; this can cause unexpected behavior in <a>Foldable</a> instances
--   that don't have a fixed number of items.
--   
--   Note that this requires <tt>t a</tt> to have a <a>Num</a> instance. If
--   you are using a list, I recommend using <a>vector-sized</a> instead:
--   it's a fixed-length vector type with a very appropriate <a>Num</a>
--   instance!
collectVar :: forall t a s. (Reifies s W, Foldable t, Functor t, Num (t a), Num a) => t (BVar s a) -> BVar s (t a)

-- | Using a <a>Traversal'</a>, extract a single value <i>inside</i> a
--   <a>BVar</a>, if it exists. If more than one traversal target exists,
--   returns te first. Meant to evoke parallels to <tt>preview</tt> from
--   lens. Really only intended to be used wth <tt>Prism'</tt>s, or
--   up-to-one target traversals.
--   
--   See documentation for <tt>^^?</tt> for more information.
previewVar :: forall b a s. (Num a, Reifies s W) => Traversal' b a -> BVar s b -> Maybe (BVar s a)

-- | Using a <a>Traversal'</a>, extract all targeted values <i>inside</i> a
--   <a>BVar</a>. Meant to evoke parallels to <a>toListOf</a> from lens.
--   
--   See documentation for <tt>^^..</tt> for more information.
toListOfVar :: forall b a s. (Num a, Reifies s W) => Traversal' b a -> BVar s b -> [BVar s a]

-- | Convert the value inside a <a>BVar</a> using a given isomorphism.
--   Useful for things like constructors.
--   
--   Warning: This is unsafe! It assumes that the isomorphisms themselves
--   have derivative 1, so will break for things like <a>exp</a> &amp;
--   <a>log</a>. Basically, don't use this for any "numeric" isomorphisms.
isoVar :: (Num a, Num b, Reifies s W) => (a -> b) -> (b -> a) -> BVar s a -> BVar s b

-- | Convert the values inside two <a>BVar</a>s using a given isomorphism.
--   Useful for things like constructors. See <a>isoVar</a> for caveats.
isoVar2 :: (Num a, Num b, Num c, Reifies s W) => (a -> b -> c) -> (c -> (a, b)) -> BVar s a -> BVar s b -> BVar s c

-- | Convert the values inside three <a>BVar</a>s using a given
--   isomorphism. Useful for things like constructors. See <a>isoVar</a>
--   for caveats.
isoVar3 :: (Num a, Num b, Num c, Num d, Reifies s W) => (a -> b -> c -> d) -> (d -> (a, b, c)) -> BVar s a -> BVar s b -> BVar s c -> BVar s d

-- | Convert the values inside a tuple of <a>BVar</a>s using a given
--   isomorphism. Useful for things like constructors. See <a>isoVar</a>
--   for caveats.
isoVarN :: (Every Num as, Num b, Reifies s W) => (Tuple as -> b) -> (b -> Tuple as) -> Prod (BVar s) as -> BVar s b

-- | Lift an <a>Op</a> with an arbitrary number of inputs to a function on
--   the appropriate number of <a>BVar</a>s.
--   
--   Should preferably be used only by libraries to provide primitive
--   <a>BVar</a> functions for their types for users.
--   
--   See <a>Numeric.Backprop#liftops</a> and documentation for
--   <a>liftOp</a> for more information, and
--   <a>Numeric.Backprop.Op#prod</a> for a mini-tutorial on using
--   <a>Prod</a> and <a>Tuple</a>.
liftOp :: forall as b s. (Reifies s W, Num b, Every Num as) => Op as b -> Prod (BVar s) as -> BVar s b

-- | Lift an <a>Op</a> with a single input to be a function on a single
--   <a>BVar</a>.
--   
--   Should preferably be used only by libraries to provide primitive
--   <a>BVar</a> functions for their types for users.
--   
--   See <a>Numeric.Backprop#liftops</a> and documentation for
--   <a>liftOp</a> for more information.
liftOp1 :: forall a b s. (Reifies s W, Num a, Num b) => Op '[a] b -> BVar s a -> BVar s b

-- | Lift an <a>Op</a> with two inputs to be a function on a two
--   <a>BVar</a>s.
--   
--   Should preferably be used only by libraries to provide primitive
--   <a>BVar</a> functions for their types for users.
--   
--   See <a>Numeric.Backprop#liftops</a> and documentation for
--   <a>liftOp</a> for more information.
liftOp2 :: forall a b c s. (Reifies s W, Num a, Num b, Num c) => Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c

-- | Lift an <a>Op</a> with three inputs to be a function on a three
--   <a>BVar</a>s.
--   
--   Should preferably be used only by libraries to provide primitive
--   <a>BVar</a> functions for their types for users.
--   
--   See <a>Numeric.Backprop#liftops</a> and documentation for
--   <a>liftOp</a> for more information.
liftOp3 :: forall a b c d s. (Reifies s W, Num a, Num b, Num c, Num d) => Op '[a, b, c] d -> BVar s a -> BVar s b -> BVar s c -> BVar s d

-- | An <tt><a>Op</a> as a</tt> describes a differentiable function from
--   <tt>as</tt> to <tt>a</tt>.
--   
--   For example, a value of type
--   
--   <pre>
--   <a>Op</a> '[Int, Bool] Double
--   </pre>
--   
--   is a function from an <a>Int</a> and a <a>Bool</a>, returning a
--   <a>Double</a>. It can be differentiated to give a <i>gradient</i> of
--   an <a>Int</a> and a <a>Bool</a> if given a total derivative for the
--   <tt>Double</tt>. If we call <a>Bool</a> &lt;math&gt;, then,
--   mathematically, it is akin to a:
--   
--   &lt;math&gt;
--   
--   See <a>runOp</a>, <a>gradOp</a>, and <a>gradOpWith</a> for examples on
--   how to run it, and <a>Op</a> for instructions on creating it.
--   
--   It is simpler to not use this type constructor directly, and instead
--   use the <a>op2</a>, <a>op1</a>, <a>op2</a>, and <a>op3</a> helper
--   smart constructors.
--   
--   See <a>Numeric.Backprop.Op#prod</a> for a mini-tutorial on using
--   <a>Prod</a> and <a>Tuple</a>.
newtype Op as a

-- | Construct an <a>Op</a> by giving a function creating the result, and
--   also a continuation on how to create the gradient, given the total
--   derivative of <tt>a</tt>.
--   
--   See the module documentation for <a>Numeric.Backprop.Op</a> for more
--   details on the function that this constructor and <a>Op</a> expect.
Op :: (Tuple as -> (a, a -> Tuple as)) -> Op as a

-- | Run the function that the <a>Op</a> encodes, returning a continuation
--   to compute the gradient, given the total derivative of <tt>a</tt>. See
--   documentation for <a>Numeric.Backprop.Op</a> for more information.
[runOpWith] :: Op as a -> Tuple as -> (a, a -> Tuple as)

-- | Create an <a>Op</a> that takes no inputs and always returns the given
--   value.
--   
--   There is no gradient, of course (using <a>gradOp</a> will give you an
--   empty tuple), because there is no input to have a gradient of.
--   
--   <pre>
--   &gt;&gt;&gt; runOp (op0 10) Ø
--   (10, Ø)
--   </pre>
--   
--   For a constant <a>Op</a> that takes input and ignores it, see
--   <a>opConst</a> and <a>opConst'</a>.
op0 :: a -> Op '[] a

-- | An <a>Op</a> that ignores all of its inputs and returns a given
--   constant value.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' (opConst 10) (1 ::&lt; 2 ::&lt; 3 ::&lt; Ø)
--   (10, 0 ::&lt; 0 ::&lt; 0 ::&lt; Ø)
--   </pre>
opConst :: (Every Num as, Known Length as) => a -> Op as a

-- | An <a>Op</a> that just returns whatever it receives. The identity
--   function.
--   
--   <pre>
--   <a>idOp</a> = <a>opIso</a> <a>id</a> <a>id</a>
--   </pre>
idOp :: Op '[a] a

-- | A version of <a>opConst</a> taking explicit <a>Length</a>, indicating
--   the number of inputs and their types.
--   
--   Requiring an explicit <a>Length</a> is mostly useful for rare
--   "extremely polymorphic" situations, where GHC can't infer the type and
--   length of the the expected input tuple. If you ever actually
--   explicitly write down <tt>as</tt> as a list of types, you should be
--   able to just use <a>opConst</a>.
opConst' :: Every Num as => Length as -> a -> Op as a

-- | Create an <a>Op</a> of a function taking one input, by giving its
--   explicit derivative. The function should return a tuple containing the
--   result of the function, and also a function taking the derivative of
--   the result and return the derivative of the input.
--   
--   If we have
--   
--   &lt;math&gt;
--   
--   Then the derivative &lt;math&gt;, it would be:
--   
--   &lt;math&gt;
--   
--   If our <a>Op</a> represents &lt;math&gt;, then the second item in the
--   resulting tuple should be a function that takes &lt;math&gt; and
--   returns &lt;math&gt;.
--   
--   As an example, here is an <a>Op</a> that squares its input:
--   
--   <pre>
--   square :: Num a =&gt; <a>Op</a> '[a] a
--   square = <a>op1</a> $ \x -&gt; (x*x, \d -&gt; 2 * d * x
--                        )
--   </pre>
--   
--   Remember that, generally, end users shouldn't directly construct
--   <a>Op</a>s; they should be provided by libraries or generated
--   automatically.
op1 :: (a -> (b, b -> a)) -> Op '[a] b

-- | Create an <a>Op</a> of a function taking two inputs, by giving its
--   explicit gradient. The function should return a tuple containing the
--   result of the function, and also a function taking the derivative of
--   the result and return the derivative of the input.
--   
--   If we have
--   
--   &lt;math&gt;
--   
--   Then the gradient &lt;math&gt; would be:
--   
--   &lt;math&gt;
--   
--   If our <a>Op</a> represents &lt;math&gt;, then the second item in the
--   resulting tuple should be a function that takes &lt;math&gt; and
--   returns &lt;math&gt;.
--   
--   As an example, here is an <a>Op</a> that multiplies its inputs:
--   
--   <pre>
--   mul :: Num a =&gt; <a>Op</a> '[a, a] a
--   mul = <tt>op2'</tt> $ \x y -&gt; (x*y, \d -&gt; (d*y, x*d)
--                        )
--   </pre>
--   
--   Remember that, generally, end users shouldn't directly construct
--   <a>Op</a>s; they should be provided by libraries or generated
--   automatically.
op2 :: (a -> b -> (c, c -> (a, b))) -> Op '[a, b] c

-- | Create an <a>Op</a> of a function taking three inputs, by giving its
--   explicit gradient. See documentation for <a>op2</a> for more details.
op3 :: (a -> b -> c -> (d, d -> (a, b, c))) -> Op '[a, b, c] d

-- | An <a>Op</a> that coerces an item into another item whose type has the
--   same runtime representation.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' opCoerce (Identity 5) :: (Int, Identity Int)
--   (5, Identity 1)
--   </pre>
--   
--   <pre>
--   <a>opCoerce</a> = <a>opIso</a> <tt>coerced</tt> <a>coerce</a>
--   </pre>
opCoerce :: Coercible a b => Op '[a] b

-- | An <a>Op</a> that takes <tt>as</tt> and returns exactly the input
--   tuple.
--   
--   <pre>
--   &gt;&gt;&gt; gradOp' opTup (1 ::&lt; 2 ::&lt; 3 ::&lt; Ø)
--   (1 ::&lt; 2 ::&lt; 3 ::&lt; Ø, 1 ::&lt; 1 ::&lt; 1 ::&lt; Ø)
--   </pre>
opTup :: Op as (Tuple as)

-- | An <a>Op</a> that runs the input value through an isomorphism.
--   
--   Warning: This is unsafe! It assumes that the isomorphisms themselves
--   have derivative 1, so will break for things like <a>exp</a> &amp;
--   <a>log</a>. Basically, don't use this for any "numeric" isomorphisms.
opIso :: (a -> b) -> (b -> a) -> Op '[a] b

-- | An <a>Op</a> that runs the input value through an isomorphism between
--   a tuple of values and a value. See <a>opIso</a> for caveats.
--   
--   In <a>Numeric.Backprop.Op</a> since version 0.1.2.0, but only exported
--   from <a>Numeric.Backprop</a> since version 0.1.3.0.
opIsoN :: (Tuple as -> b) -> (b -> Tuple as) -> Op as b

-- | An <a>Op</a> that extracts a value from an input value using a
--   <a>Lens'</a>.
--   
--   Warning: This is unsafe! It assumes that it extracts a specific value
--   unchanged, with derivative 1, so will break for things that
--   numerically manipulate things before returning them.
opLens :: Num a => Lens' a b -> Op '[a] b

-- | Create an <a>Op</a> with no gradient. Can be evaluated with
--   <a>evalOp</a>, but will throw a runtime exception when asked for the
--   gradient.
--   
--   Can be used with <tt>BVar</tt> with <tt>liftOp1</tt>, and
--   <tt>evalBP</tt> will work fine. <tt>gradBP</tt> and <tt>backprop</tt>
--   will also work fine if the result is never used in the final answer,
--   but will throw a runtime exception if the final answer depends on the
--   result of this operation.
--   
--   Useful if your only API is exposed through <i>backprop</i>. Just be
--   sure to tell your users that this will explode when finding the
--   gradient if the result is used in the final result.
noGrad1 :: (a -> b) -> Op '[a] b

-- | Create an <a>Op</a> with no gradient. Can be evaluated with
--   <a>evalOp</a>, but will throw a runtime exception when asked for the
--   gradient.
--   
--   Can be used with <tt>BVar</tt> with <tt>liftOp</tt>, and
--   <tt>evalBP</tt> will work fine. <tt>gradBP</tt> and <tt>backprop</tt>
--   will also work fine if the result is never used in the final answer,
--   but will throw a runtime exception if the final answer depends on the
--   result of this operation.
--   
--   Useful if your only API is exposed through <i>backprop</i>. Just be
--   sure to tell your users that this will explode when finding the
--   gradient if the result is used in the final result.
noGrad :: (Tuple as -> b) -> Op as b
data Prod k (f :: k -> *) (a :: [k]) :: forall k. () => (k -> *) -> [k] -> *
[Ø] :: Prod k f [] k
[:<] :: Prod k f (:) k a1 as

-- | Construct a two element Prod. Since the precedence of (:&gt;) is
--   higher than (:&lt;), we can conveniently write lists like:
--   
--   <pre>
--   &gt;&gt;&gt; a :&lt; b :&gt; c
--   </pre>
--   
--   Which is identical to:
--   
--   <pre>
--   &gt;&gt;&gt; a :&lt; b :&lt; c :&lt; Ø
--   </pre>
infix 6 :>

-- | Build a singleton Prod.
only :: () => f a -> Prod k f (:) k a [] k
head' :: () => Prod k f (:<) k a as -> f a

-- | A Prod of simple Haskell types.
type Tuple = Prod * I

-- | Cons onto a Tuple.
infixr 5 ::<

-- | Singleton Tuple.
only_ :: () => a -> Tuple (:) * a [] *
newtype I a :: * -> *
I :: a -> I a
[getI] :: I a -> a
class Reifies k (s :: k) a | s -> a


-- | Canonical strict tuples (and unit) with <a>Num</a> instances for usage
--   with <i>backprop</i>. This is here to solve the problem of orphan
--   instances in libraries and potential mismatched tuple types.
--   
--   If you are writing a library that needs to export <tt>BVar</tt>s of
--   tuples, consider using the tuples in this module so that your library
--   can have easy interoperability with other libraries using
--   <i>backprop</i>.
--   
--   Because of API decisions, <tt>backprop</tt> and <tt>gradBP</tt> only
--   work with things with <a>Num</a> instances. However, this disallows
--   default <tt>Prelude</tt> tuples (without orphan instances from
--   packages like <a>NumInstances</a>).
--   
--   Until tuples have <a>Num</a> instances in <i>base</i>, this module is
--   intended to be a workaround for situations where:
--   
--   This comes up often in cases where:
--   
--   <ol>
--   <li>A function wants to return more than one value (<tt><tt>BVar</tt>
--   s (<a>T2</a> a b)</tt></li>
--   <li>You want to uncurry a <tt>BVar</tt> function to use with
--   <tt>backprop</tt> and <tt>gradBP</tt>.</li>
--   <li>You want to use the useful <tt>Prism</tt>s automatically generated
--   by the lens library, which use tuples for multiple-constructor
--   fields.</li>
--   </ol>
--   
--   Only 2-tuples and 3-tuples are provided. Any more and you should
--   probably be using your own custom product types, with instances
--   automatically generated from something like
--   <a>one-liner-instances</a>.
--   
--   Lenses into the fields are provided, but they also work with
--   <a>_1</a>, <a>_2</a>, and <a>_3</a> from <a>Lens.Micro</a>. However,
--   note that these are incompatible with <a>_1</a>, <a>_2</a>, and
--   <a>_3</a> from <a>Control.Lens</a>.
--   
--   You can "construct" a <tt><tt>BVar</tt> s (<a>T2</a> a b)</tt> with
--   functions like <tt>isoVar</tt>.
module Numeric.Backprop.Tuple

-- | Unit ('()') with <a>Num</a>, <a>Fractional</a>, and <a>Floating</a>
--   instances.
--   
--   Be aware that the methods in its numerical instances are all
--   non-strict:
--   
--   @<tt> _ + _ = <a>T0</a> <a>negate</a> _ = <a>T0</a>
--   <a>fromIntegral</a> _ = <a>T0</a> </tt>@
data T0
T0 :: T0

-- | Strict 2-tuple with <a>Num</a>, <a>Fractional</a>, and <a>Floating</a>
--   instances.
data T2 a b
T2 :: !a -> !b -> T2 a b

-- | Convert to a Haskell tuple.
--   
--   Forms an isomorphism with <a>tupT2</a>.
t2Tup :: T2 a b -> (a, b)

-- | Convert from Haskell tuple.
--   
--   Forms an isomorphism with <a>t2Tup</a>.
tupT2 :: (a, b) -> T2 a b

-- | Uncurry a function to take in a <a>T2</a> of its arguments
uncurryT2 :: (a -> b -> c) -> T2 a b -> c

-- | Curry a function taking a <a>T2</a> of its arguments
curryT2 :: (T2 a b -> c) -> a -> b -> c

-- | Lens into the first field of a <a>T2</a>. Also exported as <a>_1</a>
--   from <a>Lens.Micro</a>.
t2_1 :: Lens (T2 a b) (T2 a' b) a a'

-- | Lens into the second field of a <a>T2</a>. Also exported as <a>_2</a>
--   from <a>Lens.Micro</a>.
t2_2 :: Lens (T2 a b) (T2 a b') b b'

-- | Strict 3-tuple with a <a>Num</a>, <a>Fractional</a>, and
--   <a>Floating</a> instances.
data T3 a b c
T3 :: !a -> !b -> !c -> T3 a b c

-- | Convert to a Haskell tuple.
--   
--   Forms an isomorphism with <a>tupT3</a>.
t3Tup :: T3 a b c -> (a, b, c)

-- | Convert from Haskell tuple.
--   
--   Forms an isomorphism with <a>t3Tup</a>.
tupT3 :: (a, b, c) -> T3 a b c

-- | Lens into the first field of a <a>T3</a>. Also exported as <a>_1</a>
--   from <a>Lens.Micro</a>.
t3_1 :: Lens (T3 a b c) (T3 a' b c) a a'

-- | Lens into the second field of a <a>T3</a>. Also exported as <a>_2</a>
--   from <a>Lens.Micro</a>.
t3_2 :: Lens (T3 a b c) (T3 a b' c) b b'

-- | Lens into the third field of a <a>T3</a>. Also exported as <a>_3</a>
--   from <a>Lens.Micro</a>.
t3_3 :: Lens (T3 a b c) (T3 a b c') c c'

-- | Uncurry a function to take in a <a>T3</a> of its arguments
uncurryT3 :: (a -> b -> c -> d) -> T3 a b c -> d

-- | Curry a function taking a <a>T3</a> of its arguments
curryT3 :: (T3 a b c -> d) -> a -> b -> c -> d

-- | Strict inductive N-tuple with a <a>Num</a>, <a>Fractional</a>, and
--   <a>Floating</a> instances.
--   
--   It is basically "yet another HList", like the one found in
--   <a>Data.Type.Product</a> and many other locations on the haskell
--   ecosystem. Because it's inductively defined, it has O(n) random
--   indexing, but is efficient for zipping and mapping and other
--   sequential consumption patterns.
--   
--   It is provided because of its <a>Num</a> instance, making it useful
--   for <i>backproup</i>. Will be obsolete when <a>Product</a> gets
--   numerical instances.
data T :: [Type] -> Type
[TNil] :: T '[]
[:&] :: !a -> !(T as) -> T (a : as)

-- | Index into a <a>T</a>.
--   
--   <i>O(i)</i>
indexT :: Index as a -> T as -> a

-- | Extract a singleton <a>T</a>
--   
--   Forms an isomorphism with <a>onlyT</a>
tOnly :: T '[a] -> a

-- | A singleton <a>T</a>
--   
--   Forms an isomorphism with <a>tOnly</a>
onlyT :: a -> T '[a]

-- | Split a <a>T</a>. For splits known at compile-time, you can use
--   <a>known</a> to derive the <a>Length</a> automatically.
--   
--   Forms an isomorphism with <a>tAppend</a>.
tSplit :: Length as -> T (as ++ bs) -> (T as, T bs)

-- | Append two <a>T</a>s.
--   
--   Forms an isomorphism with <a>tSplit</a>.
tAppend :: T as -> T bs -> T (as ++ bs)
infixr 5 `tAppend`

-- | Convert a <a>T</a> to a <a>Tuple</a>.
--   
--   Forms an isomorphism with <a>prodT</a>.
tProd :: T as -> Tuple as

-- | Convert a <a>Tuple</a> to a <a>T</a>.
--   
--   Forms an isomorphism with <a>tProd</a>.
prodT :: Tuple as -> T as

-- | Lens into a given index of a <a>T</a>.
tIx :: Index as a -> Lens' (T as) a

-- | Lens into the head of a <a>T</a>
tHead :: Lens (T (a : as)) (T (b : as)) a b

-- | Lens into the tail of a <a>T</a>
tTail :: Lens (T (a : as)) (T (a : bs)) (T as) (T bs)

-- | Lens into the initial portion of a <a>T</a>. For splits known at
--   compile-time, you can use <a>known</a> to derive the <a>Length</a>
--   automatically.
tTake :: forall as bs cs. Length as -> Lens (T (as ++ bs)) (T (cs ++ bs)) (T as) (T cs)

-- | Lens into the ending portion of a <a>T</a>. For splits known at
--   compile-time, you can use <a>known</a> to derive the <a>Length</a>
--   automatically.
tDrop :: forall as bs cs. Length as -> Lens (T (as ++ bs)) (T (as ++ cs)) (T bs) (T cs)

-- | Initialize a <a>T</a> with a Rank-N value. Mostly used internally, but
--   provided in case useful.
--   
--   Must be used with <i>TypeApplications</i> to provide the Rank-N
--   constraint.
constT :: forall c as. ListC (c <$> as) => (forall a. c a => a) -> Length as -> T as

-- | Map over a <a>T</a> with a Rank-N function. Mostly used internally,
--   but provided in case useful.
--   
--   Must be used with <i>TypeApplications</i> to provide the Rank-N
--   constraint.
mapT :: forall c as. ListC (c <$> as) => (forall a. c a => a -> a) -> T as -> T as

-- | Map over a <a>T</a> with a Rank-N function. Mostly used internally,
--   but provided in case useful.
--   
--   Must be used with <i>TypeApplications</i> to provide the Rank-N
--   constraint.
zipT :: forall c as. ListC (c <$> as) => (forall a. c a => a -> a -> a) -> T as -> T as -> T as
instance (Data.Data.Data c, Data.Data.Data b, Data.Data.Data a) => Data.Data.Data (Numeric.Backprop.Tuple.T3 a b c)
instance GHC.Base.Functor (Numeric.Backprop.Tuple.T3 a b)
instance GHC.Generics.Generic (Numeric.Backprop.Tuple.T3 a b c)
instance (GHC.Classes.Ord c, GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Numeric.Backprop.Tuple.T3 a b c)
instance (GHC.Classes.Eq c, GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Numeric.Backprop.Tuple.T3 a b c)
instance (GHC.Read.Read c, GHC.Read.Read b, GHC.Read.Read a) => GHC.Read.Read (Numeric.Backprop.Tuple.T3 a b c)
instance (GHC.Show.Show c, GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Numeric.Backprop.Tuple.T3 a b c)
instance (Data.Data.Data b, Data.Data.Data a) => Data.Data.Data (Numeric.Backprop.Tuple.T2 a b)
instance GHC.Base.Functor (Numeric.Backprop.Tuple.T2 a)
instance GHC.Generics.Generic (Numeric.Backprop.Tuple.T2 a b)
instance (GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Numeric.Backprop.Tuple.T2 a b)
instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Numeric.Backprop.Tuple.T2 a b)
instance (GHC.Read.Read b, GHC.Read.Read a) => GHC.Read.Read (Numeric.Backprop.Tuple.T2 a b)
instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Numeric.Backprop.Tuple.T2 a b)
instance Data.Data.Data Numeric.Backprop.Tuple.T0
instance GHC.Generics.Generic Numeric.Backprop.Tuple.T0
instance GHC.Classes.Ord Numeric.Backprop.Tuple.T0
instance GHC.Classes.Eq Numeric.Backprop.Tuple.T0
instance GHC.Read.Read Numeric.Backprop.Tuple.T0
instance GHC.Show.Show Numeric.Backprop.Tuple.T0
instance Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint Control.DeepSeq.NFData as) => Control.DeepSeq.NFData (Numeric.Backprop.Tuple.T as)
instance Lens.Micro.Internal.Field1 (Numeric.Backprop.Tuple.T ((':) * a as)) (Numeric.Backprop.Tuple.T ((':) * a as)) a a
instance Lens.Micro.Internal.Field2 (Numeric.Backprop.Tuple.T ((':) * a ((':) * b as))) (Numeric.Backprop.Tuple.T ((':) * a ((':) * b as))) b b
instance Lens.Micro.Internal.Field3 (Numeric.Backprop.Tuple.T ((':) * a ((':) * b ((':) * c as)))) (Numeric.Backprop.Tuple.T ((':) * a ((':) * b ((':) * c as)))) c c
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Num.Num as)) => GHC.Num.Num (Numeric.Backprop.Tuple.T as)
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Num.Num as), Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Real.Fractional as)) => GHC.Real.Fractional (Numeric.Backprop.Tuple.T as)
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Num.Num as), Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Real.Fractional as), Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Float.Floating as)) => GHC.Float.Floating (Numeric.Backprop.Tuple.T as)
instance Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint Data.Semigroup.Semigroup as) => Data.Semigroup.Semigroup (Numeric.Backprop.Tuple.T as)
instance (Type.Class.Known.Known [*] (Data.Type.Length.Length *) as, Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint Data.Semigroup.Semigroup as), Type.Family.List.ListC ((Type.Family.List.<$>) * GHC.Types.Constraint GHC.Base.Monoid as)) => GHC.Base.Monoid (Numeric.Backprop.Tuple.T as)
instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b, Control.DeepSeq.NFData c) => Control.DeepSeq.NFData (Numeric.Backprop.Tuple.T3 a b c)
instance Data.Bifunctor.Bifunctor (Numeric.Backprop.Tuple.T3 a)
instance Lens.Micro.Internal.Field1 (Numeric.Backprop.Tuple.T3 a b c) (Numeric.Backprop.Tuple.T3 a' b c) a a'
instance Lens.Micro.Internal.Field2 (Numeric.Backprop.Tuple.T3 a b c) (Numeric.Backprop.Tuple.T3 a b' c) b b'
instance Lens.Micro.Internal.Field3 (Numeric.Backprop.Tuple.T3 a b c) (Numeric.Backprop.Tuple.T3 a b c') c c'
instance (GHC.Num.Num a, GHC.Num.Num b, GHC.Num.Num c) => GHC.Num.Num (Numeric.Backprop.Tuple.T3 a b c)
instance (GHC.Real.Fractional a, GHC.Real.Fractional b, GHC.Real.Fractional c) => GHC.Real.Fractional (Numeric.Backprop.Tuple.T3 a b c)
instance (GHC.Float.Floating a, GHC.Float.Floating b, GHC.Float.Floating c) => GHC.Float.Floating (Numeric.Backprop.Tuple.T3 a b c)
instance (Data.Semigroup.Semigroup a, Data.Semigroup.Semigroup b, Data.Semigroup.Semigroup c) => Data.Semigroup.Semigroup (Numeric.Backprop.Tuple.T3 a b c)
instance (Data.Semigroup.Semigroup a, Data.Semigroup.Semigroup b, Data.Semigroup.Semigroup c, GHC.Base.Monoid a, GHC.Base.Monoid b, GHC.Base.Monoid c) => GHC.Base.Monoid (Numeric.Backprop.Tuple.T3 a b c)
instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b) => Control.DeepSeq.NFData (Numeric.Backprop.Tuple.T2 a b)
instance Data.Bifunctor.Bifunctor Numeric.Backprop.Tuple.T2
instance Lens.Micro.Internal.Field1 (Numeric.Backprop.Tuple.T2 a b) (Numeric.Backprop.Tuple.T2 a' b) a a'
instance Lens.Micro.Internal.Field2 (Numeric.Backprop.Tuple.T2 a b) (Numeric.Backprop.Tuple.T2 a b') b b'
instance (GHC.Num.Num a, GHC.Num.Num b) => GHC.Num.Num (Numeric.Backprop.Tuple.T2 a b)
instance (GHC.Real.Fractional a, GHC.Real.Fractional b) => GHC.Real.Fractional (Numeric.Backprop.Tuple.T2 a b)
instance (GHC.Float.Floating a, GHC.Float.Floating b) => GHC.Float.Floating (Numeric.Backprop.Tuple.T2 a b)
instance (Data.Semigroup.Semigroup a, Data.Semigroup.Semigroup b) => Data.Semigroup.Semigroup (Numeric.Backprop.Tuple.T2 a b)
instance (Data.Semigroup.Semigroup a, Data.Semigroup.Semigroup b, GHC.Base.Monoid a, GHC.Base.Monoid b) => GHC.Base.Monoid (Numeric.Backprop.Tuple.T2 a b)
instance Control.DeepSeq.NFData Numeric.Backprop.Tuple.T0
instance GHC.Num.Num Numeric.Backprop.Tuple.T0
instance GHC.Real.Fractional Numeric.Backprop.Tuple.T0
instance GHC.Float.Floating Numeric.Backprop.Tuple.T0
instance Data.Semigroup.Semigroup Numeric.Backprop.Tuple.T0
instance GHC.Base.Monoid Numeric.Backprop.Tuple.T0


-- | Some lifted versions of common functions found in <tt>Prelude</tt> (or
--   <i>base</i> in general).
--   
--   Intended to work with <a>Functor</a> <i> <a>Foldable</a> </i>
--   <a>Traversable</a> instances with "fixed" number of items, i.e.
--   <a>vector-sized</a> vectors. There might be unintended consequences
--   when using it with instances where the number of items is not fixed.
--   
--   This module is intended to be a catch-all one, so feel free to suggest
--   other functions or submit a PR if you think one would make sense.
module Prelude.Backprop

-- | Lifted <a>sum</a>
sum :: forall t a s. (Foldable t, Functor t, Num (t a), Num a, Reifies s W) => BVar s (t a) -> BVar s a

-- | Lifted <a>product</a>
product :: forall t a s. (Foldable t, Functor t, Num (t a), Fractional a, Reifies s W) => BVar s (t a) -> BVar s a

-- | Lifted <a>length</a>.
length :: forall t a b s. (Foldable t, Num (t a), Num b, Reifies s W) => BVar s (t a) -> BVar s b

-- | Lifted <a>minimum</a>. Undefined for situations where <a>minimum</a>
--   would be undefined.
minimum :: forall t a s. (Foldable t, Functor t, Num a, Ord a, Num (t a), Reifies s W) => BVar s (t a) -> BVar s a

-- | Lifted <a>maximum</a>. Undefined for situations where <a>maximum</a>
--   would be undefined.
maximum :: forall t a s. (Foldable t, Functor t, Num a, Ord a, Num (t a), Reifies s W) => BVar s (t a) -> BVar s a

-- | Lifted <a>traverse</a>. Lifts backpropagatable functions to be
--   backpropagatable functions on <a>Traversable</a> <a>Functor</a>s.
--   
--   Really intended only for <a>Traversable</a> and <a>Applicative</a>
--   instances with fixed number of items; untintended consequences might
--   arise when using it with containers with variable number of items.
traverse :: forall t f a b s. (Traversable t, Applicative f, Foldable f, Num a, Num b, Num (f (t b)), Num (t b), Reifies s W) => (BVar s a -> f (BVar s b)) -> BVar s (t a) -> BVar s (f (t b))

-- | Lifted <a>fmap</a>. Lifts backpropagatable functions to be
--   backpropagatable functions on <a>Traversable</a> <a>Functor</a>s.
--   
--   Really intended only for <a>Functor</a> instances with fixed number of
--   items; untintended consequences might arise when using it with
--   containers with variable number of items.
fmap :: forall f a b s. (Traversable f, Num a, Num b, Num (f b), Reifies s W) => (BVar s a -> BVar s b) -> BVar s (f a) -> BVar s (f b)

-- | Alias for <a>fmap</a>.
(<$>) :: forall f a b s. (Traversable f, Num a, Num b, Num (f b), Reifies s W) => (BVar s a -> BVar s b) -> BVar s (f a) -> BVar s (f b)

-- | Lifted <a>pure</a>. Really intended only for <a>Applicative</a>
--   instances with fixed number of items; untintended consequences might
--   arise when using it with containers with variable number of items.
pure :: forall t a s. (Foldable t, Applicative t, Num (t a), Num a, Reifies s W) => BVar s a -> BVar s (t a)

-- | Lifted <a>liftA2</a>. Lifts backpropagatable functions to be
--   backpropagatable functions on <a>Traversable</a> <a>Applicative</a>s.
--   
--   Really intended only for <a>Traversable</a> and <a>Applicative</a>
--   instances with fixed number of items; untintended consequences might
--   arise when using it with containers with variable number of items.
liftA2 :: forall f a b c s. (Traversable f, Applicative f, Num a, Num b, Num c, Num (f c), Reifies s W) => (BVar s a -> BVar s b -> BVar s c) -> BVar s (f a) -> BVar s (f b) -> BVar s (f c)

-- | Lifted <a>liftA3</a>. Lifts backpropagatable functions to be
--   backpropagatable functions on <a>Traversable</a> <a>Applicative</a>s.
--   
--   Really intended only for <a>Traversable</a> and <a>Applicative</a>
--   instances with fixed number of items; untintended consequences might
--   arise when using it with containers with variable number of items.
liftA3 :: forall f a b c d s. (Traversable f, Applicative f, Num a, Num b, Num c, Num d, Num (f d), Reifies s W) => (BVar s a -> BVar s b -> BVar s c -> BVar s d) -> BVar s (f a) -> BVar s (f b) -> BVar s (f c) -> BVar s (f d)

-- | Coerce items inside a <a>BVar</a>.
coerce :: forall a b s. (Coercible a b, Num a, Num b, Reifies s W) => BVar s a -> BVar s b
