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


-- | Heterogeneous automatic differentation
--   
--   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>https://backprop.jle.im</a> for official introduction and
--   documentation.
@package backprop
@version 0.2.5.0


-- | Provides the <a>Backprop</a> typeclass, a class for values that can be
--   used for backpropagation.
--   
--   This class replaces the old (version 0.1) API relying on <a>Num</a>.
module Numeric.Backprop.Class

-- | Class of values that can be backpropagated in general.
--   
--   For instances of <a>Num</a>, these methods can be given by
--   <a>zeroNum</a>, <a>addNum</a>, and <a>oneNum</a>. There are also
--   generic options given in <a>Numeric.Backprop.Class</a> for functors,
--   <a>IsList</a> instances, and <a>Generic</a> instances.
--   
--   <pre>
--   instance <a>Backprop</a> <a>Double</a> where
--       <a>zero</a> = <a>zeroNum</a>
--       <a>add</a> = <a>addNum</a>
--       <a>one</a> = <a>oneNum</a>
--   </pre>
--   
--   If you leave the body of an instance declaration blank, GHC Generics
--   will be used to derive instances if the type has a single constructor
--   and each field is an instance of <a>Backprop</a>.
--   
--   To ensure that backpropagation works in a sound way, should obey the
--   laws:
--   
--   <ul>
--   <li><i><i>identity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Also implies preservation of information, making <tt><a>zipWith</a>
--   (<a>+</a>)</tt> an illegal implementation for lists and vectors.
--   
--   This is only expected to be true up to potential "extra zeroes" in
--   <tt>x</tt> and <tt>y</tt> in the result.
--   
--   <ul>
--   <li><i><i>commutativity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x y = <a>add</a> y x</pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>associativity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>add</a> y z) = <a>add</a> (<a>add</a> x y)
--   z</pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>idempotence</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>unital</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   Note that not all values in the backpropagation process needs all of
--   these methods: Only the "final result" needs <a>one</a>, for example.
--   These are all grouped under one typeclass for convenience in defining
--   instances, and also to talk about sensible laws. For fine-grained
--   control, use the "explicit" versions of library functions (for
--   example, in <a>Numeric.Backprop.Explicit</a>) instead of
--   <a>Backprop</a> based ones.
--   
--   This typeclass replaces the reliance on <a>Num</a> of the previous API
--   (v0.1). <a>Num</a> is strictly more powerful than <a>Backprop</a>, and
--   is a stronger constraint on types than is necessary for proper
--   backpropagating. In particular, <a>fromInteger</a> is a problem for
--   many types, preventing useful backpropagation for lists,
--   variable-length vectors (like <a>Data.Vector</a>) and variable-size
--   matrices from linear algebra libraries like <i>hmatrix</i> and
--   <i>accelerate</i>.
class Backprop a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent:
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>zeroNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>zeroFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericZero</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
zero :: Backprop a => a -> a

-- | Add together two values of a type. To combine contributions of
--   gradients, so should be information-preserving:
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Should be as <i>strict</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>addNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>addIsList</a> for a definition for instances of
--   <a>IsList</a>. If left blank, will automatically be <a>genericAdd</a>,
--   a pre-built definition for instances of <a>Generic</a> with one
--   constructor whose fields are all themselves instances of
--   <a>Backprop</a>.
add :: Backprop a => a -> a -> a

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   As the library uses it, the most important law is:
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   That is, <tt><a>one</a> x</tt> is the gradient of the identity
--   function with respect to its input.
--   
--   Ideally should be idempotent:
--   
--   <ul>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>oneNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>oneFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericOne</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
one :: Backprop a => a -> a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent:
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>zeroNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>zeroFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericZero</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
zero :: (Backprop a, Generic a, GZero (Rep a)) => a -> a

-- | Add together two values of a type. To combine contributions of
--   gradients, so should be information-preserving:
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Should be as <i>strict</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>addNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>addIsList</a> for a definition for instances of
--   <a>IsList</a>. If left blank, will automatically be <a>genericAdd</a>,
--   a pre-built definition for instances of <a>Generic</a> with one
--   constructor whose fields are all themselves instances of
--   <a>Backprop</a>.
add :: (Backprop a, Generic a, GAdd (Rep a)) => a -> a -> a

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   As the library uses it, the most important law is:
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   That is, <tt><a>one</a> x</tt> is the gradient of the identity
--   function with respect to its input.
--   
--   Ideally should be idempotent:
--   
--   <ul>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>oneNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>oneFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericOne</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
one :: (Backprop a, Generic a, GOne (Rep a)) => a -> a

-- | <a>zero</a> for instances of <a>Num</a>.
--   
--   Is lazy in its argument.
zeroNum :: Num a => a -> a

-- | <a>add</a> for instances of <a>Num</a>.
addNum :: Num a => a -> a -> a

-- | <a>one</a> for instances of <a>Num</a>.
--   
--   Is lazy in its argument.
oneNum :: Num a => a -> a

-- | <a>zero</a> for instances of <a>Vector</a>.
zeroVec :: (Vector v a, Backprop a) => v a -> v a

-- | <a>add</a> for instances of <a>Vector</a>. Automatically pads the end
--   of the shorter vector with zeroes.
addVec :: (Vector v a, Backprop a) => v a -> v a -> v a

-- | <a>one</a> for instances of <a>Vector</a>.
oneVec :: (Vector v a, Backprop a) => v a -> v a

-- | <a>zero</a> for instances of <a>Vector</a> when the contained type is
--   an instance of <a>Num</a>. Is potentially more performant than
--   <a>zeroVec</a> when the vectors are larger.
--   
--   See <a>NumVec</a> for a <a>Backprop</a> instance for <a>Vector</a>
--   instances that uses this for <a>zero</a>.
zeroVecNum :: (Vector v a, Num a) => v a -> v a

-- | <a>one</a> for instances of <a>Vector</a> when the contained type is
--   an instance of <a>Num</a>. Is potentially more performant than
--   <a>oneVec</a> when the vectors are larger.
--   
--   See <a>NumVec</a> for a <a>Backprop</a> instance for <a>Vector</a>
--   instances that uses this for <a>one</a>.
oneVecNum :: (Vector v a, Num a) => v a -> v a

-- | <a>zero</a> for <a>Functor</a> instances.
zeroFunctor :: (Functor f, Backprop a) => f a -> f a

-- | <a>add</a> for instances of <a>IsList</a>. Automatically pads the end
--   of the "shorter" value with zeroes.
addIsList :: (IsList a, Backprop (Item a)) => a -> a -> a

-- | <a>add</a> for types that are isomorphic to a list. Automatically pads
--   the end of the "shorter" value with zeroes.
addAsList :: Backprop b => (a -> [b]) -> ([b] -> a) -> a -> a -> a

-- | <a>one</a> for instances of <a>Functor</a>.
oneFunctor :: (Functor f, Backprop a) => f a -> f a

-- | <a>zero</a> using GHC Generics; works if all fields are instances of
--   <a>Backprop</a>.
genericZero :: (Generic a, GZero (Rep a)) => a -> a

-- | <a>add</a> using GHC Generics; works if all fields are instances of
--   <a>Backprop</a>, but only for values with single constructors.
genericAdd :: (Generic a, GAdd (Rep a)) => a -> a -> a

-- | <a>one</a> using GHC Generics; works if all fields are instaces of
--   <a>Backprop</a>.
genericOne :: (Generic a, GOne (Rep a)) => a -> a

-- | A newtype wrapper over an <tt>f a</tt> for <tt><a>Applicative</a>
--   f</tt> that gives a free <a>Backprop</a> instance (as well as
--   <a>Num</a> etc. instances).
--   
--   Useful for performing backpropagation over functions that require some
--   monadic context (like <a>IO</a>) to perform.
newtype ABP f a
ABP :: f a -> ABP f a
[runABP] :: ABP f a -> f a

-- | A newtype wrapper over an instance of <a>Num</a> that gives a free
--   <a>Backprop</a> instance.
--   
--   Useful for things like <i>DerivingVia</i>, or for avoiding orphan
--   instances.
newtype NumBP a
NumBP :: a -> NumBP a
[runNumBP] :: NumBP a -> a

-- | Newtype wrapper around a <tt>v a</tt> for <tt><a>Vector</a> v a</tt>,
--   that gives a more efficient <a>Backprop</a> instance for <i>long</i>
--   vectors when <tt>a</tt> is an instance of <a>Num</a>. The normal
--   <a>Backprop</a> instance for vectors will map <a>zero</a> or
--   <a>one</a> over all items; this instance will completely ignore the
--   contents of the original vector and instead produce a new vector of
--   the same length, with all <tt>0</tt> or <tt>1</tt> using the
--   <a>Num</a> instance of <tt>a</tt> (essentially using <a>zeroVecNum</a>
--   and <a>oneVecNum</a> instead of <a>zeroVec</a> and <a>oneVec</a>).
--   
--   <a>add</a> is essentially the same as normal, but using <a>+</a>
--   instead of the type's <a>add</a>.
newtype NumVec v a
NumVec :: v a -> NumVec v a
[runNumVec] :: NumVec v a -> v a

-- | Helper class for automatically deriving <a>zero</a> using GHC
--   Generics.
class GZero f

-- | Helper class for automatically deriving <a>add</a> using GHC Generics.
class GAdd f

-- | Helper class for automatically deriving <a>one</a> using GHC Generics.
class GOne f
instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Numeric.Backprop.Class.ABP f)
instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Numeric.Backprop.Class.ABP f)
instance GHC.Base.MonadPlus f => GHC.Base.MonadPlus (Numeric.Backprop.Class.ABP f)
instance GHC.Base.Alternative f => GHC.Base.Alternative (Numeric.Backprop.Class.ABP f)
instance GHC.Base.Monad f => GHC.Base.Monad (Numeric.Backprop.Class.ABP f)
instance GHC.Base.Applicative f => GHC.Base.Applicative (Numeric.Backprop.Class.ABP f)
instance GHC.Base.Functor f => GHC.Base.Functor (Numeric.Backprop.Class.ABP f)
instance GHC.Generics.Generic (Numeric.Backprop.Class.ABP f a)
instance (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a, Data.Data.Data (f a)) => Data.Data.Data (Numeric.Backprop.Class.ABP f a)
instance GHC.Classes.Ord (f a) => GHC.Classes.Ord (Numeric.Backprop.Class.ABP f a)
instance GHC.Classes.Eq (f a) => GHC.Classes.Eq (Numeric.Backprop.Class.ABP f a)
instance GHC.Read.Read (f a) => GHC.Read.Read (Numeric.Backprop.Class.ABP f a)
instance GHC.Show.Show (f a) => GHC.Show.Show (Numeric.Backprop.Class.ABP f a)
instance Data.Traversable.Traversable v => Data.Traversable.Traversable (Numeric.Backprop.Class.NumVec v)
instance Data.Foldable.Foldable v => Data.Foldable.Foldable (Numeric.Backprop.Class.NumVec v)
instance GHC.Base.MonadPlus v => GHC.Base.MonadPlus (Numeric.Backprop.Class.NumVec v)
instance GHC.Base.Alternative v => GHC.Base.Alternative (Numeric.Backprop.Class.NumVec v)
instance GHC.Base.Monad v => GHC.Base.Monad (Numeric.Backprop.Class.NumVec v)
instance GHC.Base.Applicative v => GHC.Base.Applicative (Numeric.Backprop.Class.NumVec v)
instance GHC.Base.Functor v => GHC.Base.Functor (Numeric.Backprop.Class.NumVec v)
instance GHC.Generics.Generic (Numeric.Backprop.Class.NumVec v a)
instance (Data.Typeable.Internal.Typeable v, Data.Typeable.Internal.Typeable a, Data.Data.Data (v a)) => Data.Data.Data (Numeric.Backprop.Class.NumVec v a)
instance GHC.Classes.Ord (v a) => GHC.Classes.Ord (Numeric.Backprop.Class.NumVec v a)
instance GHC.Classes.Eq (v a) => GHC.Classes.Eq (Numeric.Backprop.Class.NumVec v a)
instance GHC.Read.Read (v a) => GHC.Read.Read (Numeric.Backprop.Class.NumVec v a)
instance GHC.Show.Show (v a) => GHC.Show.Show (Numeric.Backprop.Class.NumVec v a)
instance GHC.Float.Floating a => GHC.Float.Floating (Numeric.Backprop.Class.NumBP a)
instance GHC.Real.Fractional a => GHC.Real.Fractional (Numeric.Backprop.Class.NumBP a)
instance GHC.Num.Num a => GHC.Num.Num (Numeric.Backprop.Class.NumBP a)
instance Data.Traversable.Traversable Numeric.Backprop.Class.NumBP
instance Data.Foldable.Foldable Numeric.Backprop.Class.NumBP
instance GHC.Base.Functor Numeric.Backprop.Class.NumBP
instance GHC.Generics.Generic (Numeric.Backprop.Class.NumBP a)
instance Data.Data.Data a => Data.Data.Data (Numeric.Backprop.Class.NumBP a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Numeric.Backprop.Class.NumBP a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Numeric.Backprop.Class.NumBP a)
instance GHC.Read.Read a => GHC.Read.Read (Numeric.Backprop.Class.NumBP a)
instance GHC.Show.Show a => GHC.Show.Show (Numeric.Backprop.Class.NumBP a)
instance GHC.Num.Num a => Numeric.Backprop.Class.Backprop (Numeric.Backprop.Class.NumBP a)
instance (Data.Vector.Generic.Base.Vector v a, GHC.Num.Num a) => Numeric.Backprop.Class.Backprop (Numeric.Backprop.Class.NumVec v a)
instance (GHC.Base.Applicative f, Numeric.Backprop.Class.Backprop a) => Numeric.Backprop.Class.Backprop (Numeric.Backprop.Class.ABP f a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.GZero (GHC.Generics.K1 i a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.GAdd (GHC.Generics.K1 i a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.GOne (GHC.Generics.K1 i a)
instance Numeric.Backprop.Class.Backprop GHC.Types.Int
instance Numeric.Backprop.Class.Backprop GHC.Integer.Type.Integer
instance Numeric.Backprop.Class.Backprop GHC.Natural.Natural
instance Numeric.Backprop.Class.Backprop GHC.Word.Word8
instance Numeric.Backprop.Class.Backprop GHC.Types.Word
instance Numeric.Backprop.Class.Backprop GHC.Word.Word16
instance Numeric.Backprop.Class.Backprop GHC.Word.Word32
instance Numeric.Backprop.Class.Backprop GHC.Word.Word64
instance GHC.Real.Integral a => Numeric.Backprop.Class.Backprop (GHC.Real.Ratio a)
instance GHC.Float.RealFloat a => Numeric.Backprop.Class.Backprop (Data.Complex.Complex a)
instance Numeric.Backprop.Class.Backprop GHC.Types.Float
instance Numeric.Backprop.Class.Backprop GHC.Types.Double
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Vector.Vector a)
instance (Data.Vector.Unboxed.Base.Unbox a, Numeric.Backprop.Class.Backprop a) => Numeric.Backprop.Class.Backprop (Data.Vector.Unboxed.Base.Vector a)
instance (Foreign.Storable.Storable a, Numeric.Backprop.Class.Backprop a) => Numeric.Backprop.Class.Backprop (Data.Vector.Storable.Vector a)
instance (Data.Primitive.Types.Prim a, Numeric.Backprop.Class.Backprop a) => Numeric.Backprop.Class.Backprop (Data.Vector.Primitive.Vector a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop [a]
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (GHC.Base.NonEmpty a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Sequence.Internal.Seq a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (GHC.Base.Maybe a)
instance Numeric.Backprop.Class.Backprop ()
instance (Numeric.Backprop.Class.Backprop a, Numeric.Backprop.Class.Backprop b) => Numeric.Backprop.Class.Backprop (a, b)
instance (Numeric.Backprop.Class.Backprop a, Numeric.Backprop.Class.Backprop b, Numeric.Backprop.Class.Backprop c) => Numeric.Backprop.Class.Backprop (a, b, c)
instance (Numeric.Backprop.Class.Backprop a, Numeric.Backprop.Class.Backprop b, Numeric.Backprop.Class.Backprop c, Numeric.Backprop.Class.Backprop d) => Numeric.Backprop.Class.Backprop (a, b, c, d)
instance (Numeric.Backprop.Class.Backprop a, Numeric.Backprop.Class.Backprop b, Numeric.Backprop.Class.Backprop c, Numeric.Backprop.Class.Backprop d, Numeric.Backprop.Class.Backprop e) => Numeric.Backprop.Class.Backprop (a, b, c, d, e)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Functor.Identity.Identity a)
instance Numeric.Backprop.Class.Backprop (Data.Proxy.Proxy a)
instance Numeric.Backprop.Class.Backprop w => Numeric.Backprop.Class.Backprop (Data.Functor.Const.Const w a)
instance Numeric.Backprop.Class.Backprop Data.Void.Void
instance (Numeric.Backprop.Class.Backprop a, GHC.Classes.Ord k) => Numeric.Backprop.Class.Backprop (Data.Map.Internal.Map k a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.IntMap.Internal.IntMap a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (GHC.Generics.K1 i a p)
instance Numeric.Backprop.Class.Backprop (f p) => Numeric.Backprop.Class.Backprop (GHC.Generics.M1 i c f p)
instance (Numeric.Backprop.Class.Backprop (f p), Numeric.Backprop.Class.Backprop (g p)) => Numeric.Backprop.Class.Backprop ((GHC.Generics.:*:) f g p)
instance Numeric.Backprop.Class.Backprop (GHC.Generics.V1 p)
instance Numeric.Backprop.Class.Backprop (GHC.Generics.U1 p)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Semigroup.Internal.Sum a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Semigroup.Internal.Product a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Semigroup.Option a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Semigroup.First a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Semigroup.Last a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Monoid.First a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Monoid.Last a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (Data.Semigroup.Internal.Dual a)
instance (Numeric.Backprop.Class.Backprop a, Numeric.Backprop.Class.Backprop b) => Numeric.Backprop.Class.Backprop (Data.Semigroup.Arg a b)
instance (Numeric.Backprop.Class.Backprop (f a), Numeric.Backprop.Class.Backprop (g a)) => Numeric.Backprop.Class.Backprop (Data.Functor.Product.Product f g a)
instance Numeric.Backprop.Class.Backprop (f (g a)) => Numeric.Backprop.Class.Backprop (Data.Functor.Compose.Compose f g a)
instance Numeric.Backprop.Class.Backprop a => Numeric.Backprop.Class.Backprop (r -> a)
instance (Numeric.Backprop.Class.Backprop a, GHC.Base.Applicative m) => Numeric.Backprop.Class.Backprop (Control.Arrow.Kleisli m r a)
instance Numeric.Backprop.Class.Backprop Debug.SimpleReflect.Expr.Expr
instance (Numeric.Backprop.Class.GOne f, Numeric.Backprop.Class.GOne g) => Numeric.Backprop.Class.GOne (f GHC.Generics.:*: g)
instance (Numeric.Backprop.Class.GOne f, Numeric.Backprop.Class.GOne g) => Numeric.Backprop.Class.GOne (f GHC.Generics.:+: g)
instance Numeric.Backprop.Class.GOne GHC.Generics.V1
instance Numeric.Backprop.Class.GOne GHC.Generics.U1
instance Numeric.Backprop.Class.GOne f => Numeric.Backprop.Class.GOne (GHC.Generics.M1 i c f)
instance Numeric.Backprop.Class.GOne f => Numeric.Backprop.Class.GOne (f GHC.Generics.:.: g)
instance (Numeric.Backprop.Class.GAdd f, Numeric.Backprop.Class.GAdd g) => Numeric.Backprop.Class.GAdd (f GHC.Generics.:*: g)
instance Numeric.Backprop.Class.GAdd GHC.Generics.V1
instance Numeric.Backprop.Class.GAdd GHC.Generics.U1
instance Numeric.Backprop.Class.GAdd f => Numeric.Backprop.Class.GAdd (GHC.Generics.M1 i c f)
instance Numeric.Backprop.Class.GAdd f => Numeric.Backprop.Class.GAdd (f GHC.Generics.:.: g)
instance (Numeric.Backprop.Class.GZero f, Numeric.Backprop.Class.GZero g) => Numeric.Backprop.Class.GZero (f GHC.Generics.:*: g)
instance (Numeric.Backprop.Class.GZero f, Numeric.Backprop.Class.GZero g) => Numeric.Backprop.Class.GZero (f GHC.Generics.:+: g)
instance Numeric.Backprop.Class.GZero GHC.Generics.V1
instance Numeric.Backprop.Class.GZero GHC.Generics.U1
instance Numeric.Backprop.Class.GZero f => Numeric.Backprop.Class.GZero (GHC.Generics.M1 i c f)
instance Numeric.Backprop.Class.GZero f => Numeric.Backprop.Class.GZero (f GHC.Generics.:.: g)
instance Control.DeepSeq.NFData (f a) => Control.DeepSeq.NFData (Numeric.Backprop.Class.ABP f a)
instance (GHC.Base.Applicative f, GHC.Num.Num a) => GHC.Num.Num (Numeric.Backprop.Class.ABP f a)
instance (GHC.Base.Applicative f, GHC.Real.Fractional a) => GHC.Real.Fractional (Numeric.Backprop.Class.ABP f a)
instance (GHC.Base.Applicative f, GHC.Float.Floating a) => GHC.Float.Floating (Numeric.Backprop.Class.ABP f a)
instance Control.DeepSeq.NFData (v a) => Control.DeepSeq.NFData (Numeric.Backprop.Class.NumVec v a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Numeric.Backprop.Class.NumBP a)
instance GHC.Base.Applicative Numeric.Backprop.Class.NumBP
instance GHC.Base.Monad Numeric.Backprop.Class.NumBP


-- | 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.
--   
--   To use these <a>Op</a>s with the backprop library, they can be made to
--   work with <tt>BVar</tt>s using <tt>liftOp</tt>, <tt>liftOp1</tt>,
--   <tt>liftOp2</tt>, and <tt>liftOp3</tt>.
--   
--   If you are writing a library, see
--   <a>https://backprop.jle.im/06-equipping-your-library.html</a> for a
--   guide for equipping your library with backpropatable operations using
--   <a>Op</a>s.
--   
--   See also <a>this guide</a> for writing Ops manually on your own
--   numerical functions.
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>Rec</a> and 'Rec Identity'.
--   
--   To <i>use</i> an <a>Op</a> with the backprop library, see
--   <tt>liftOp</tt>, <tt>liftOp1</tt>, <tt>liftOp2</tt>, and
--   <tt>liftOp3</tt>.
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 :: Rec Identity as -> (a, a -> Rec Identity 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 -> Rec Identity as -> (a, a -> Rec Identity as)

-- | A record is parameterized by a universe <tt>u</tt>, an interpretation
--   <tt>f</tt> and a list of rows <tt>rs</tt>. The labels or indices of
--   the record are given by inhabitants of the kind <tt>u</tt>; the type
--   of values at any label <tt>r :: u</tt> is given by its interpretation
--   <tt>f r :: *</tt>.
data Rec (a :: u -> *) (b :: [u]) :: forall u. () => u -> * -> [u] -> *
[RNil] :: Rec a ([] :: [u])
[:&] :: Rec a r : rs

-- | 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 :&amp; 5 :&amp; RNil)
--   (15, 5 :&amp; 3 :&amp; RNil)
--   </pre>
runOp :: Num a => Op as a -> Rec Identity as -> (a, Rec Identity as)

-- | Run the function that an <a>Op</a> encodes, to get the result.
--   
--   <pre>
--   &gt;&gt;&gt; runOp (op2 (*)) (3 :&amp; 5 :&amp; RNil)
--   15
--   </pre>
evalOp :: Op as a -> Rec Identity 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 :&amp; 5 :&amp; RNil)
--   5 :&amp; 3 :&amp; RNil
--   -- 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 -> Rec Identity as -> Rec Identity 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 -> Rec Identity as -> a -> Rec Identity 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) RNil
--   (10, RNil)
--   </pre>
--   
--   For a constant <a>Op</a> that takes input and ignores it, see
--   <a>opConst</a> and <tt>opConst'</tt>.
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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (10, 0 :&amp; 0 :&amp; 0 :&amp; RNil)
--   </pre>
opConst :: forall as a. (AllConstrained Num as, RecApplicative 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

-- | 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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (1 :&amp; 2 :&amp; 3 :&amp; RNil, 1 :&amp; 1 :&amp; 1 :&amp; RNil)
--   </pre>
opTup :: Op as (Rec Identity 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 :: (Rec Identity as -> b) -> (b -> Rec Identity 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 :: (Rec Identity 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 :: forall as bs c. (AllConstrained Num as, RecApplicative as) => Rec (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 :: (AllConstrained Num as, RecApplicative 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>
(~.) :: (AllConstrained Num as, RecApplicative as) => Op '[b] c -> Op as b -> Op as c
infixr 9 ~.

-- | <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 (Data.Vinyl.Core.RecApplicative as, Data.Vinyl.TypeLevel.AllConstrained GHC.Num.Num as, GHC.Num.Num a) => GHC.Num.Num (Numeric.Backprop.Op.Op as a)
instance (Data.Vinyl.Core.RecApplicative as, Data.Vinyl.TypeLevel.AllConstrained GHC.Num.Num as, GHC.Real.Fractional a) => GHC.Real.Fractional (Numeric.Backprop.Op.Op as a)
instance (Data.Vinyl.Core.RecApplicative as, Data.Vinyl.TypeLevel.AllConstrained GHC.Float.Floating as, Data.Vinyl.TypeLevel.AllConstrained GHC.Real.Fractional as, Data.Vinyl.TypeLevel.AllConstrained GHC.Num.Num as, GHC.Float.Floating a) => GHC.Float.Floating (Numeric.Backprop.Op.Op as a)


-- | Provides "explicit" versions of all of the functions in
--   <a>Numeric.Backprop</a>. Instead of relying on a <a>Backprop</a>
--   instance, allows you to manually provide <a>zero</a>, <a>add</a>, and
--   <a>one</a> on a per-value basis.
--   
--   It is recommended you use <a>Numeric.Backprop</a> or
--   <a>Numeric.Backprop.Num</a> instead, unless your type has no
--   <a>Num</a> instance, or you else you want to avoid defining orphan
--   <a>Backprop</a> instances for external types. Can also be useful if
--   mixing and matching styles.
--   
--   See <a>Numeric.Backprop</a> for fuller documentation on using these
--   functions.
--   
--   WARNING: API of this module can be considered only "semi-stable";
--   while the API of <a>Numeric.Backprop</a> and
--   <a>Numeric.Backprop.Num</a> are kept consistent, some argument order
--   changes might happen in this module to reflect changes in underlying
--   implementation.
module Numeric.Backprop.Explicit

-- | 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>.
--   
--   If you have control over your data type definitions, you can also use
--   <a>splitBV</a> and <a>joinBV</a> to manipulate data types by easily
--   extracting fields out of a <a>BVar</a> of data types and creating
--   <a>BVar</a>s of data types out of <a>BVar</a>s of their fields. See
--   <a>Numeric.Backprop#hkd</a> for a tutorial on this use pattern.
--   
--   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. See
--   <a>https://backprop.jle.im/08-equipping-your-library.html</a> for a
--   detailed guide.
--   
--   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

-- | Class of values that can be backpropagated in general.
--   
--   For instances of <a>Num</a>, these methods can be given by
--   <a>zeroNum</a>, <a>addNum</a>, and <a>oneNum</a>. There are also
--   generic options given in <a>Numeric.Backprop.Class</a> for functors,
--   <a>IsList</a> instances, and <a>Generic</a> instances.
--   
--   <pre>
--   instance <a>Backprop</a> <a>Double</a> where
--       <a>zero</a> = <a>zeroNum</a>
--       <a>add</a> = <a>addNum</a>
--       <a>one</a> = <a>oneNum</a>
--   </pre>
--   
--   If you leave the body of an instance declaration blank, GHC Generics
--   will be used to derive instances if the type has a single constructor
--   and each field is an instance of <a>Backprop</a>.
--   
--   To ensure that backpropagation works in a sound way, should obey the
--   laws:
--   
--   <ul>
--   <li><i><i>identity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Also implies preservation of information, making <tt><a>zipWith</a>
--   (<a>+</a>)</tt> an illegal implementation for lists and vectors.
--   
--   This is only expected to be true up to potential "extra zeroes" in
--   <tt>x</tt> and <tt>y</tt> in the result.
--   
--   <ul>
--   <li><i><i>commutativity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x y = <a>add</a> y x</pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>associativity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>add</a> y z) = <a>add</a> (<a>add</a> x y)
--   z</pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>idempotence</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>unital</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   Note that not all values in the backpropagation process needs all of
--   these methods: Only the "final result" needs <a>one</a>, for example.
--   These are all grouped under one typeclass for convenience in defining
--   instances, and also to talk about sensible laws. For fine-grained
--   control, use the "explicit" versions of library functions (for
--   example, in <a>Numeric.Backprop.Explicit</a>) instead of
--   <a>Backprop</a> based ones.
--   
--   This typeclass replaces the reliance on <a>Num</a> of the previous API
--   (v0.1). <a>Num</a> is strictly more powerful than <a>Backprop</a>, and
--   is a stronger constraint on types than is necessary for proper
--   backpropagating. In particular, <a>fromInteger</a> is a problem for
--   many types, preventing useful backpropagation for lists,
--   variable-length vectors (like <a>Data.Vector</a>) and variable-size
--   matrices from linear algebra libraries like <i>hmatrix</i> and
--   <i>accelerate</i>.
class Backprop a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent:
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>zeroNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>zeroFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericZero</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
zero :: Backprop a => a -> a

-- | Add together two values of a type. To combine contributions of
--   gradients, so should be information-preserving:
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Should be as <i>strict</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>addNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>addIsList</a> for a definition for instances of
--   <a>IsList</a>. If left blank, will automatically be <a>genericAdd</a>,
--   a pre-built definition for instances of <a>Generic</a> with one
--   constructor whose fields are all themselves instances of
--   <a>Backprop</a>.
add :: Backprop a => a -> a -> a

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   As the library uses it, the most important law is:
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   That is, <tt><a>one</a> x</tt> is the gradient of the identity
--   function with respect to its input.
--   
--   Ideally should be idempotent:
--   
--   <ul>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>oneNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>oneFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericOne</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
one :: Backprop a => a -> a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent:
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>zeroNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>zeroFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericZero</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
zero :: (Backprop a, Generic a, GZero (Rep a)) => a -> a

-- | Add together two values of a type. To combine contributions of
--   gradients, so should be information-preserving:
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Should be as <i>strict</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>addNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>addIsList</a> for a definition for instances of
--   <a>IsList</a>. If left blank, will automatically be <a>genericAdd</a>,
--   a pre-built definition for instances of <a>Generic</a> with one
--   constructor whose fields are all themselves instances of
--   <a>Backprop</a>.
add :: (Backprop a, Generic a, GAdd (Rep a)) => a -> a -> a

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   As the library uses it, the most important law is:
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   That is, <tt><a>one</a> x</tt> is the gradient of the identity
--   function with respect to its input.
--   
--   Ideally should be idempotent:
--   
--   <ul>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>oneNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>oneFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericOne</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
one :: (Backprop a, Generic a, GOne (Rep a)) => a -> a

-- | A newtype wrapper over an <tt>f a</tt> for <tt><a>Applicative</a>
--   f</tt> that gives a free <a>Backprop</a> instance (as well as
--   <a>Num</a> etc. instances).
--   
--   Useful for performing backpropagation over functions that require some
--   monadic context (like <a>IO</a>) to perform.
newtype ABP f a
ABP :: f a -> ABP f a
[runABP] :: ABP f a -> f a

-- | A newtype wrapper over an instance of <a>Num</a> that gives a free
--   <a>Backprop</a> instance.
--   
--   Useful for things like <i>DerivingVia</i>, or for avoiding orphan
--   instances.
newtype NumBP a
NumBP :: a -> NumBP a
[runNumBP] :: NumBP a -> a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent: Applying the function twice is the same as
--   applying it just once.
--   
--   Each type should ideally only have one <a>ZeroFunc</a>. This coherence
--   constraint is given by the typeclass <a>Backprop</a>.
newtype ZeroFunc a
ZF :: a -> a -> ZeroFunc a
[runZF] :: ZeroFunc a -> a -> a

-- | If a type has a <a>Num</a> instance, this is the canonical
--   <a>ZeroFunc</a>.
zfNum :: Num a => ZeroFunc a

-- | <a>ZeroFunc</a>s for every item in a type level list based on their
--   <a>Num</a> instances
zfNums :: (RecApplicative as, AllConstrained Num as) => Rec ZeroFunc as

-- | The canonical <a>ZeroFunc</a> for instances of <a>Backprop</a>.
zeroFunc :: Backprop a => ZeroFunc a

-- | Generate an <a>ZeroFunc</a> for every type in a type-level list, if
--   every type has an instance of <a>Backprop</a>.
zeroFuncs :: (RecApplicative as, AllConstrained Backprop as) => Rec ZeroFunc as

-- | <a>zeroFunc</a> for instances of <a>Functor</a>
zfFunctor :: (Backprop a, Functor f) => ZeroFunc (f a)

-- | Add together two values of a type. To combine contributions of
--   gradients, so should ideally be information-preserving.
--   
--   See laws for <a>Backprop</a> for the laws this should be expected to
--   preserve. Namely, it should be commutative and associative, with an
--   identity for a valid <a>ZeroFunc</a>.
--   
--   Each type should ideally only have one <a>AddFunc</a>. This coherence
--   constraint is given by the typeclass <a>Backprop</a>.
newtype AddFunc a
AF :: a -> a -> a -> AddFunc a
[runAF] :: AddFunc a -> a -> a -> a

-- | If a type has a <a>Num</a> instance, this is the canonical
--   <a>AddFunc</a>.
afNum :: Num a => AddFunc a

-- | <a>ZeroFunc</a>s for every item in a type level list based on their
--   <a>Num</a> instances
afNums :: (RecApplicative as, AllConstrained Num as) => Rec AddFunc as

-- | The canonical <a>AddFunc</a> for instances of <a>Backprop</a>.
addFunc :: Backprop a => AddFunc a

-- | Generate an <a>AddFunc</a> for every type in a type-level list, if
--   every type has an instance of <a>Backprop</a>.
addFuncs :: (RecApplicative as, AllConstrained Backprop as) => Rec AddFunc as

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   Should be idempotent: Applying the function twice is the same as
--   applying it just once.
--   
--   Each type should ideally only have one <a>OneFunc</a>. This coherence
--   constraint is given by the typeclass <a>Backprop</a>.
newtype OneFunc a
OF :: a -> a -> OneFunc a
[runOF] :: OneFunc a -> a -> a

-- | If a type has a <a>Num</a> instance, this is the canonical
--   <a>OneFunc</a>.
ofNum :: Num a => OneFunc a

-- | <a>ZeroFunc</a>s for every item in a type level list based on their
--   <a>Num</a> instances
ofNums :: (RecApplicative as, AllConstrained Num as) => Rec OneFunc as

-- | The canonical <a>OneFunc</a> for instances of <a>Backprop</a>.
oneFunc :: Backprop a => OneFunc a

-- | Generate an <a>OneFunc</a> for every type in a type-level list, if
--   every type has an instance of <a>Backprop</a>.
oneFuncs :: (RecApplicative as, AllConstrained Backprop as) => Rec OneFunc as

-- | <a>OneFunc</a> for instances of <a>Functor</a>
ofFunctor :: (Backprop a, Functor f) => OneFunc (f a)

-- | <a>backprop</a>, but with explicit <a>zero</a> and <a>one</a>.
backprop :: ZeroFunc a -> OneFunc 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.
--   
--   See documentation of <a>backprop</a> for more information.
evalBP :: (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> b

-- | <a>gradBP</a>, but with explicit <a>zero</a> and <a>one</a>.
gradBP :: ZeroFunc a -> OneFunc b -> (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> a

-- | <a>backpropWith</a>, but with explicit <a>zero</a>.
--   
--   Note that argument order changed in v0.2.4.
backpropWith :: ZeroFunc a -> (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> (b, b -> a)

-- | <a>evalBP</a> but with no arguments. Useful when everything is just
--   given through <a>constVar</a>.
evalBP0 :: (forall s. Reifies s W => BVar s a) -> a

-- | <a>backprop2</a>, but with explicit <a>zero</a> and <a>one</a>.
backprop2 :: ZeroFunc a -> ZeroFunc b -> OneFunc 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>gradBP2</a> with explicit <a>zero</a> and <a>one</a>.
gradBP2 :: ZeroFunc a -> ZeroFunc b -> OneFunc c -> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (a, b)

-- | <a>backpropWith2</a>, but with explicit <a>zero</a>.
--   
--   Note that argument order changed in v0.2.4.
backpropWith2 :: ZeroFunc a -> ZeroFunc b -> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (c, c -> (a, b))

-- | <a>backpropN</a>, but with explicit <a>zero</a> and <a>one</a>.
backpropN :: forall as b. () => Rec ZeroFunc as -> OneFunc b -> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> (b, Rec Identity 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 => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> b

-- | <a>gradBP</a>, Nbut with explicit <a>zero</a> and <a>one</a>.
gradBPN :: Rec ZeroFunc as -> OneFunc b -> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> Rec Identity as

-- | <a>backpropWithN</a>, but with explicit <a>zero</a> and <a>one</a>.
--   
--   Note that argument order changed in v0.2.4.
backpropWithN :: forall as b. () => Rec ZeroFunc as -> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> (b, b -> Rec Identity as)

-- | Given a section of some functor, records in that functor of any size
--   are inhabited.
class RecApplicative (rs :: [u])

-- | Constraint that all types in a type-level list satisfy a constraint.

-- | 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

-- | Shorter alias for <a>constVar</a>, inspired by the <i>ad</i> library.
auto :: a -> BVar s a

-- | Coerce a <a>BVar</a> contents. Useful for things like newtype
--   wrappers.
coerceVar :: Coercible a b => BVar s a -> BVar s b

-- | <a>viewVar</a>, but with explicit <a>add</a> and <a>zero</a>.
viewVar :: forall a b s. Reifies s W => AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a

-- | <a>setVar</a>, but with explicit <a>add</a> and <a>zero</a>.
setVar :: forall a b s. Reifies s W => AddFunc a -> AddFunc b -> ZeroFunc a -> Lens' b a -> BVar s a -> BVar s b -> BVar s b

-- | <a>overVar</a> with explicit <a>add</a> and <a>zero</a>.
overVar :: Reifies s W => AddFunc a -> AddFunc b -> ZeroFunc a -> ZeroFunc b -> Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b

-- | <a>sequenceVar</a>, but with explicit <a>add</a> and <a>zero</a>.
sequenceVar :: forall t a s. (Reifies s W, Traversable t) => AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)

-- | <a>collectVar</a>, but with explicit <a>add</a> and <a>zero</a>.
collectVar :: forall t a s. (Reifies s W, Foldable t, Functor t) => AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)

-- | <a>previewVar</a>, but with explicit <a>add</a> and <a>zero</a>.
previewVar :: forall b a s. Reifies s W => AddFunc a -> ZeroFunc b -> Traversal' b a -> BVar s b -> Maybe (BVar s a)

-- | <a>toListOfVar</a>, but with explicit <a>add</a> and <a>zero</a>.
toListOfVar :: forall b a s. Reifies s W => AddFunc a -> ZeroFunc b -> Traversal' b a -> BVar s b -> [BVar s a]

-- | <a>isoVar</a> with explicit <a>add</a> and <a>zero</a>.
isoVar :: Reifies s W => AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b

-- | <a>isoVar2</a> with explicit <a>add</a> and <a>zero</a>.
isoVar2 :: Reifies s W => AddFunc a -> AddFunc b -> (a -> b -> c) -> (c -> (a, b)) -> BVar s a -> BVar s b -> BVar s c

-- | <a>isoVar3</a> with explicit <a>add</a> and <a>zero</a>.
isoVar3 :: Reifies s W => AddFunc a -> AddFunc b -> AddFunc c -> (a -> b -> c -> d) -> (d -> (a, b, c)) -> BVar s a -> BVar s b -> BVar s c -> BVar s d

-- | <a>isoVarN</a> with explicit <a>add</a> and <a>zero</a>.
isoVarN :: Reifies s W => Rec AddFunc as -> (Rec Identity as -> b) -> (b -> Rec Identity as) -> Rec (BVar s) as -> BVar s b

-- | <a>liftOp</a>, but with explicit <a>add</a> and <a>zero</a>.
liftOp :: forall as b s. Reifies s W => Rec AddFunc as -> Op as b -> Rec (BVar s) as -> BVar s b

-- | <a>liftOp1</a>, but with explicit <a>add</a> and <a>zero</a>.
liftOp1 :: forall a b s. Reifies s W => AddFunc a -> Op '[a] b -> BVar s a -> BVar s b

-- | <a>liftOp2</a>, but with explicit <a>add</a> and <a>zero</a>.
liftOp2 :: forall a b c s. Reifies s W => AddFunc a -> AddFunc b -> Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c

-- | <a>liftOp3</a>, but with explicit <a>add</a> and <a>zero</a>.
liftOp3 :: forall a b c d s. Reifies s W => AddFunc a -> AddFunc b -> AddFunc c -> Op '[a, b, c] d -> BVar s a -> BVar s b -> BVar s c -> BVar s d

-- | <a>splitBV</a> with explicit <a>add</a> and <a>zero</a>.
splitBV :: forall z f s as. (Generic (z f), Generic (z (BVar s)), BVGroup s as (Rep (z f)) (Rep (z (BVar s))), Reifies s W) => AddFunc (Rep (z f) ()) -> Rec AddFunc as -> ZeroFunc (z f) -> Rec ZeroFunc as -> BVar s (z f) -> z (BVar s)

-- | <a>joinBV</a> with explicit <a>add</a> and <a>zero</a>.
joinBV :: forall z f s as. (Generic (z f), Generic (z (BVar s)), BVGroup s as (Rep (z f)) (Rep (z (BVar s))), Reifies s W) => AddFunc (z f) -> Rec AddFunc as -> ZeroFunc (Rep (z f) ()) -> Rec ZeroFunc as -> z (BVar s) -> BVar s (z f)

-- | Helper class for generically "splitting" and "joining" <a>BVar</a>s
--   into constructors. See <a>splitBV</a> and <a>joinBV</a>.
--   
--   See <a>Numeric.Backprop#hkd</a> for a tutorial on how to use this.
--   
--   Instances should be available for types made with one constructor
--   whose fields are all instances of <a>Backprop</a>, with a
--   <a>Generic</a> instance.
class BVGroup s as i o | o -> i, i -> as

-- | 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>Rec</a> and 'Rec Identity'.
--   
--   To <i>use</i> an <a>Op</a> with the backprop library, see
--   <tt>liftOp</tt>, <tt>liftOp1</tt>, <tt>liftOp2</tt>, and
--   <tt>liftOp3</tt>.
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 :: Rec Identity as -> (a, a -> Rec Identity 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 -> Rec Identity as -> (a, a -> Rec Identity 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) RNil
--   (10, RNil)
--   </pre>
--   
--   For a constant <a>Op</a> that takes input and ignores it, see
--   <a>opConst</a> and <tt>opConst'</tt>.
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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (10, 0 :&amp; 0 :&amp; 0 :&amp; RNil)
--   </pre>
opConst :: forall as a. (AllConstrained Num as, RecApplicative 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>bpOp</a> with explicit <a>zero</a>.
bpOp :: Rec ZeroFunc as -> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Op as 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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (1 :&amp; 2 :&amp; 3 :&amp; RNil, 1 :&amp; 1 :&amp; 1 :&amp; RNil)
--   </pre>
opTup :: Op as (Rec Identity 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 :: (Rec Identity as -> b) -> (b -> Rec Identity 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 :: (Rec Identity as -> b) -> Op as b

-- | A record is parameterized by a universe <tt>u</tt>, an interpretation
--   <tt>f</tt> and a list of rows <tt>rs</tt>. The labels or indices of
--   the record are given by inhabitants of the kind <tt>u</tt>; the type
--   of values at any label <tt>r :: u</tt> is given by its interpretation
--   <tt>f r :: *</tt>.
data Rec (a :: u -> *) (b :: [u]) :: forall u. () => u -> * -> [u] -> *
[RNil] :: Rec a ([] :: [u])
[:&] :: Rec a r : rs
class Reifies (s :: k) a | s -> a
instance Numeric.Backprop.Explicit.BVGroup s '[] (GHC.Generics.K1 i a) (GHC.Generics.K1 i (Numeric.Backprop.Internal.BVar s a))
instance Numeric.Backprop.Explicit.BVGroup s as i o => Numeric.Backprop.Explicit.BVGroup s as (GHC.Generics.M1 p c i) (GHC.Generics.M1 p c o)
instance Numeric.Backprop.Explicit.BVGroup s '[] GHC.Generics.V1 GHC.Generics.V1
instance Numeric.Backprop.Explicit.BVGroup s '[] GHC.Generics.U1 GHC.Generics.U1
instance (Data.Reflection.Reifies s Numeric.Backprop.Internal.W, Numeric.Backprop.Explicit.BVGroup s as i1 o1, Numeric.Backprop.Explicit.BVGroup s bs i2 o2, cs ~ (as Data.Vinyl.TypeLevel.++ bs), Data.Vinyl.Core.RecApplicative as) => Numeric.Backprop.Explicit.BVGroup s (i1 () : i2 () : cs) (i1 GHC.Generics.:*: i2) (o1 GHC.Generics.:*: o2)
instance (Data.Reflection.Reifies s Numeric.Backprop.Internal.W, Numeric.Backprop.Explicit.BVGroup s as i1 o1, Numeric.Backprop.Explicit.BVGroup s bs i2 o2, cs ~ (as Data.Vinyl.TypeLevel.++ bs), Data.Vinyl.Core.RecApplicative as) => Numeric.Backprop.Explicit.BVGroup s (i1 () : i2 () : cs) (i1 GHC.Generics.:+: i2) (o1 GHC.Generics.:+: o2)


-- | Provides the exact same API as <a>Numeric.Backprop</a>, except
--   requiring <a>Num</a> instances for all types involved instead of
--   <tt>Backprop</tt> instances.
--   
--   This was the original API of the library (for version 0.1).
--   
--   <a>Num</a> is strictly more powerful than <tt>Backprop</tt>, and is a
--   stronger constraint on types than is necessary for proper
--   backpropagating. In particular, <a>fromInteger</a> is a problem for
--   many types, preventing useful backpropagation for lists,
--   variable-length vectors (like <a>Data.Vector</a>) and variable-size
--   matrices from linear algebra libraries like <i>hmatrix</i> and
--   <i>accelerate</i>.
--   
--   However, this module might be useful in situations where you are
--   working with external types with <a>Num</a> instances, and you want to
--   avoid writing orphan instances for external types.
--   
--   If you have external types that are not <a>Num</a> instances, consider
--   instead <a>Numeric.Backprop.External</a>.
--   
--   If you need a <a>Num</a> instance for tuples, you can use the orphan
--   instances in the
--   &lt;<a>https://hackage.haskell.org/package/NumInstances</a>
--   NumInstances&gt; package (in particular,
--   <a>Data.NumInstances.Tuple</a>) if you are writing an application and
--   do not have to worry about orphan instances.
--   
--   See <a>Numeric.Backprop</a> for fuller documentation on using these
--   functions.
module Numeric.Backprop.Num

-- | 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>.
--   
--   If you have control over your data type definitions, you can also use
--   <a>splitBV</a> and <a>joinBV</a> to manipulate data types by easily
--   extracting fields out of a <a>BVar</a> of data types and creating
--   <a>BVar</a>s of data types out of <a>BVar</a>s of their fields. See
--   <a>Numeric.Backprop#hkd</a> for a tutorial on this use pattern.
--   
--   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. See
--   <a>https://backprop.jle.im/08-equipping-your-library.html</a> for a
--   detailed guide.
--   
--   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

-- | <a>backprop</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   See module documentation for <a>Numeric.Backprop.Num</a> for
--   information on using this with tuples.
backprop :: (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.
--   
--   See documentation of <a>backprop</a> for more information.
evalBP :: (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> b

-- | <a>gradBP</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
gradBP :: (Num a, Num b) => (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> a

-- | <a>backpropWith</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   See module documentation for <a>Numeric.Backprop.Num</a> for
--   information on using this with tuples.
--   
--   Note that argument order changed in v0.2.4.
backpropWith :: Num a => (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> (b, b -> a)

-- | <a>evalBP</a> but with no arguments. Useful when everything is just
--   given through <a>constVar</a>.
evalBP0 :: (forall s. Reifies s W => BVar s a) -> a

-- | <a>backprop2</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
backprop2 :: (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>gradBP2</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
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)

-- | <a>backpropWith2</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Note that argument order changed in v0.2.4.
backpropWith2 :: (Num a, Num b) => (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (c, c -> (a, b))

-- | <a>backpropN</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   The <tt><a>AllConstrained</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>AllConstrained</a> <a>Num</a> as</tt> should be fulfilled
--   automatically.
backpropN :: (AllConstrained Num as, RecApplicative as, Num b) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> (b, Rec Identity 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 => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> b

-- | <a>gradBPN</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
gradBPN :: (AllConstrained Num as, RecApplicative as, Num b) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> Rec Identity as

-- | <a>backpropWithN</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   See <a>backpropN</a> for information on the <a>AllConstrained</a>
--   constraint.
--   
--   Note that argument order changed in v0.2.4.
backpropWithN :: (AllConstrained Num as, RecApplicative as) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> (b, b -> Rec Identity as)

-- | 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

-- | Shorter alias for <a>constVar</a>, inspired by the <i>ad</i> library.
auto :: a -> BVar s a

-- | Coerce a <a>BVar</a> contents. Useful for things like newtype
--   wrappers.
coerceVar :: Coercible a b => BVar s a -> BVar s b

-- | <a>^^.</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
(^^.) :: forall b a s. (Num a, Num b, Reifies s W) => BVar s b -> Lens' b a -> BVar s a
infixl 8 ^^.

-- | <a>.~~</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
(.~~) :: (Num a, Num b, Reifies s W) => Lens' b a -> BVar s a -> BVar s b -> BVar s b
infixl 8 .~~

-- | <a>%~~</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
(%~~) :: (Num a, Num b, Reifies s W) => Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b
infixr 4 %~~

-- | <a>^^?</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Note that many automatically-generated prisms by the <i>lens</i>
--   package use tuples, which cannot work this this by default (because
--   tuples 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 b, Num a, Reifies s W) => BVar s b -> Traversal' b a -> Maybe (BVar s a)
infixl 8 ^^?

-- | <a>^^..</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
(^^..) :: forall b a s. (Num b, Num a, Reifies s W) => BVar s b -> Traversal' b a -> [BVar s a]

-- | <a>^^?!</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Like <a>^^?!</a>, is *UNSAFE*.
(^^?!) :: forall b a s. (Num b, Num a, Reifies s W) => BVar s b -> Traversal' b a -> BVar s a
infixl 8 ^^?!

-- | <a>viewVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
viewVar :: forall b a s. (Num a, Num b, Reifies s W) => Lens' b a -> BVar s b -> BVar s a

-- | <a>setVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
setVar :: forall a b s. (Num a, Num b, Reifies s W) => Lens' b a -> BVar s a -> BVar s b -> BVar s b

-- | <a>overVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
overVar :: (Num a, Num b, Reifies s W) => Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b

-- | <a>sequenceVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Since v0.2.4, requires a <a>Num</a> constraint on <tt>t a</tt>.
sequenceVar :: (Traversable t, Num a, Reifies s W) => BVar s (t a) -> t (BVar s a)

-- | <a>collectVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Prior to v0.2.3, required a <a>Num</a> constraint on <tt>t a</tt>.
collectVar :: (Foldable t, Functor t, Num a, Reifies s W) => t (BVar s a) -> BVar s (t a)

-- | <a>previewVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   See documentation for <a>^^?</a> for more information and important
--   notes.
previewVar :: forall b a s. (Num b, Num a, Reifies s W) => Traversal' b a -> BVar s b -> Maybe (BVar s a)

-- | <a>toListOfVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
toListOfVar :: forall b a s. (Num b, Num a, Reifies s W) => Traversal' b a -> BVar s b -> [BVar s a]

-- | <a>isoVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
isoVar :: (Num a, Reifies s W) => (a -> b) -> (b -> a) -> BVar s a -> BVar s b

-- | <a>isoVar</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
isoVar2 :: (Num a, Num b, Reifies s W) => (a -> b -> c) -> (c -> (a, b)) -> BVar s a -> BVar s b -> BVar s c

-- | <a>isoVar3</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
isoVar3 :: (Num a, Num b, Num c, Reifies s W) => (a -> b -> c -> d) -> (d -> (a, b, c)) -> BVar s a -> BVar s b -> BVar s c -> BVar s d

-- | <a>isoVarN</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
isoVarN :: (AllConstrained Num as, RecApplicative as, Reifies s W) => (Rec Identity as -> b) -> (b -> Rec Identity as) -> Rec (BVar s) as -> BVar s b

-- | <a>liftOp</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
liftOp :: (AllConstrained Num as, RecApplicative as, Reifies s W) => Op as b -> Rec (BVar s) as -> BVar s b

-- | <a>liftOp1</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
liftOp1 :: (Num a, Reifies s W) => Op '[a] b -> BVar s a -> BVar s b

-- | <a>liftOp2</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
liftOp2 :: (Num a, Num b, Reifies s W) => Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c

-- | <a>liftOp3</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
liftOp3 :: (Num a, Num b, Num c, Reifies s W) => 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>Rec</a> and 'Rec Identity'.
--   
--   To <i>use</i> an <a>Op</a> with the backprop library, see
--   <tt>liftOp</tt>, <tt>liftOp1</tt>, <tt>liftOp2</tt>, and
--   <tt>liftOp3</tt>.
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 :: Rec Identity as -> (a, a -> Rec Identity 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 -> Rec Identity as -> (a, a -> Rec Identity 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) RNil
--   (10, RNil)
--   </pre>
--   
--   For a constant <a>Op</a> that takes input and ignores it, see
--   <a>opConst</a> and <tt>opConst'</tt>.
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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (10, 0 :&amp; 0 :&amp; 0 :&amp; RNil)
--   </pre>
opConst :: forall as a. (AllConstrained Num as, RecApplicative 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>bpOp</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
bpOp :: (AllConstrained Num as, RecApplicative as) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Op as 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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (1 :&amp; 2 :&amp; 3 :&amp; RNil, 1 :&amp; 1 :&amp; 1 :&amp; RNil)
--   </pre>
opTup :: Op as (Rec Identity 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 :: (Rec Identity as -> b) -> (b -> Rec Identity 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 :: (Rec Identity as -> b) -> Op as b

-- | A record is parameterized by a universe <tt>u</tt>, an interpretation
--   <tt>f</tt> and a list of rows <tt>rs</tt>. The labels or indices of
--   the record are given by inhabitants of the kind <tt>u</tt>; the type
--   of values at any label <tt>r :: u</tt> is given by its interpretation
--   <tt>f r :: *</tt>.
data Rec (a :: u -> *) (b :: [u]) :: forall u. () => u -> * -> [u] -> *
[RNil] :: Rec a ([] :: [u])
[:&] :: Rec a r : rs
class Reifies (s :: k) a | s -> 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.
--   
--   See the <a>homepage</a> for an introduction and walkthrough.
--   
--   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>
--   <tt>evalBP</tt> :: (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.
--   
--   Refer to the <a>homepage</a> for more information and links to
--   demonstrations and tutorials, or dive striaght in by reading the docs
--   for <a>BVar</a>.
--   
--   If you are writing a library, see
--   <a>https://backprop.jle.im/08-equipping-your-library.html</a> for a
--   guide for equipping your library with backpropatable operations.
--   
--   In the original version 0.1, this module required <a>Num</a> instances
--   for methods instead of <a>Backprop</a> instances. This interface is
--   still available in <a>Numeric.Backprop.Num</a>, which has the same API
--   as this module, except with <a>Num</a> constraints on all values
--   instead of <a>Backprop</a> constraints.
--   
--   See <a>Prelude.Backprop.Explicit</a> for a version allowing you to
--   provide <a>zero</a>, <a>add</a>, and <a>one</a> explicitly, which can
--   be useful when attempting to avoid orphan instances or when mixing
--   both <a>Backprop</a> and <a>Num</a> styles.
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>.
--   
--   If you have control over your data type definitions, you can also use
--   <a>splitBV</a> and <a>joinBV</a> to manipulate data types by easily
--   extracting fields out of a <a>BVar</a> of data types and creating
--   <a>BVar</a>s of data types out of <a>BVar</a>s of their fields. See
--   <a>Numeric.Backprop#hkd</a> for a tutorial on this use pattern.
--   
--   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. See
--   <a>https://backprop.jle.im/08-equipping-your-library.html</a> for a
--   detailed guide.
--   
--   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

-- | Class of values that can be backpropagated in general.
--   
--   For instances of <a>Num</a>, these methods can be given by
--   <a>zeroNum</a>, <a>addNum</a>, and <a>oneNum</a>. There are also
--   generic options given in <a>Numeric.Backprop.Class</a> for functors,
--   <a>IsList</a> instances, and <a>Generic</a> instances.
--   
--   <pre>
--   instance <a>Backprop</a> <a>Double</a> where
--       <a>zero</a> = <a>zeroNum</a>
--       <a>add</a> = <a>addNum</a>
--       <a>one</a> = <a>oneNum</a>
--   </pre>
--   
--   If you leave the body of an instance declaration blank, GHC Generics
--   will be used to derive instances if the type has a single constructor
--   and each field is an instance of <a>Backprop</a>.
--   
--   To ensure that backpropagation works in a sound way, should obey the
--   laws:
--   
--   <ul>
--   <li><i><i>identity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Also implies preservation of information, making <tt><a>zipWith</a>
--   (<a>+</a>)</tt> an illegal implementation for lists and vectors.
--   
--   This is only expected to be true up to potential "extra zeroes" in
--   <tt>x</tt> and <tt>y</tt> in the result.
--   
--   <ul>
--   <li><i><i>commutativity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x y = <a>add</a> y x</pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>associativity</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>add</a> y z) = <a>add</a> (<a>add</a> x y)
--   z</pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>idempotence</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   <ul>
--   <li><i><i>unital</i></i></li>
--   </ul>
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   Note that not all values in the backpropagation process needs all of
--   these methods: Only the "final result" needs <a>one</a>, for example.
--   These are all grouped under one typeclass for convenience in defining
--   instances, and also to talk about sensible laws. For fine-grained
--   control, use the "explicit" versions of library functions (for
--   example, in <a>Numeric.Backprop.Explicit</a>) instead of
--   <a>Backprop</a> based ones.
--   
--   This typeclass replaces the reliance on <a>Num</a> of the previous API
--   (v0.1). <a>Num</a> is strictly more powerful than <a>Backprop</a>, and
--   is a stronger constraint on types than is necessary for proper
--   backpropagating. In particular, <a>fromInteger</a> is a problem for
--   many types, preventing useful backpropagation for lists,
--   variable-length vectors (like <a>Data.Vector</a>) and variable-size
--   matrices from linear algebra libraries like <i>hmatrix</i> and
--   <i>accelerate</i>.
class Backprop a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent:
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>zeroNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>zeroFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericZero</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
zero :: Backprop a => a -> a

-- | Add together two values of a type. To combine contributions of
--   gradients, so should be information-preserving:
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Should be as <i>strict</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>addNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>addIsList</a> for a definition for instances of
--   <a>IsList</a>. If left blank, will automatically be <a>genericAdd</a>,
--   a pre-built definition for instances of <a>Generic</a> with one
--   constructor whose fields are all themselves instances of
--   <a>Backprop</a>.
add :: Backprop a => a -> a -> a

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   As the library uses it, the most important law is:
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   That is, <tt><a>one</a> x</tt> is the gradient of the identity
--   function with respect to its input.
--   
--   Ideally should be idempotent:
--   
--   <ul>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>oneNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>oneFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericOne</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
one :: Backprop a => a -> a

-- | "Zero out" all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 0</tt>. For vectors and matrices, this should
--   set all components to zero, the additive identity.
--   
--   Should be idempotent:
--   
--   <ul>
--   <li><pre><a>zero</a> <a>.</a> <a>zero</a> = <a>zero</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>zeroNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>zeroFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericZero</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
zero :: (Backprop a, Generic a, GZero (Rep a)) => a -> a

-- | Add together two values of a type. To combine contributions of
--   gradients, so should be information-preserving:
--   
--   <ul>
--   <li><pre><a>add</a> x (<a>zero</a> y) = x</pre></li>
--   <li><pre><a>add</a> (<a>zero</a> x) y = y</pre></li>
--   </ul>
--   
--   Should be as <i>strict</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>addNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>addIsList</a> for a definition for instances of
--   <a>IsList</a>. If left blank, will automatically be <a>genericAdd</a>,
--   a pre-built definition for instances of <a>Generic</a> with one
--   constructor whose fields are all themselves instances of
--   <a>Backprop</a>.
add :: (Backprop a, Generic a, GAdd (Rep a)) => a -> a -> a

-- | <a>One</a> all components of a value. For scalar values, this should
--   just be <tt><a>const</a> 1</tt>. For vectors and matrices, this should
--   set all components to one, the multiplicative identity.
--   
--   As the library uses it, the most important law is:
--   
--   <ul>
--   <li><pre><a>one</a> = <tt>gradBP</tt> <a>id</a></pre></li>
--   </ul>
--   
--   That is, <tt><a>one</a> x</tt> is the gradient of the identity
--   function with respect to its input.
--   
--   Ideally should be idempotent:
--   
--   <ul>
--   <li><pre><a>one</a> <a>.</a> <a>one</a> = <a>one</a></pre></li>
--   </ul>
--   
--   Should be as <i>lazy</i> as possible. This behavior is observed for
--   all instances provided by this library.
--   
--   See <a>oneNum</a> for a pre-built definition for instances of
--   <a>Num</a> and <a>oneFunctor</a> for a definition for instances of
--   <a>Functor</a>. If left blank, will automatically be
--   <a>genericOne</a>, a pre-built definition for instances of
--   <a>Generic</a> whose fields are all themselves instances of
--   <a>Backprop</a>.
one :: (Backprop a, Generic a, GOne (Rep a)) => a -> a

-- | A newtype wrapper over an <tt>f a</tt> for <tt><a>Applicative</a>
--   f</tt> that gives a free <a>Backprop</a> instance (as well as
--   <a>Num</a> etc. instances).
--   
--   Useful for performing backpropagation over functions that require some
--   monadic context (like <a>IO</a>) to perform.
newtype ABP f a
ABP :: f a -> ABP f a
[runABP] :: ABP f a -> f a

-- | A newtype wrapper over an instance of <a>Num</a> that gives a free
--   <a>Backprop</a> instance.
--   
--   Useful for things like <i>DerivingVia</i>, or for avoiding orphan
--   instances.
newtype NumBP a
NumBP :: a -> NumBP a
[runNumBP] :: NumBP a -> 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, 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.
backprop :: (Backprop a, Backprop 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.
--   
--   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.
--   
--   If you want to provide an explicit "final gradient" for the end, see
--   <a>backpropWith</a>.
gradBP :: (Backprop a, Backprop b) => (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> a

-- | A version of <a>backprop</a> that allows you to specify the gradent of
--   your "final result" in with respect to the output of your function.
--   
--   Typically, this is just the scalar 1, or a value of components that
--   are all 1.
--   
--   Instead of taking the <tt>b</tt> gradient, the you may provide a <tt>b
--   -&gt; b</tt>, which <a>backpropWith</a> calls with the result of your
--   function as the argument. This allows you to return something with the
--   correct "shape", if not a scalar.
--   
--   <a>backprop</a> is essentially <a>backpropWith</a> with
--   <tt><a>const</a> 1</tt> for scalars and <a>Num</a> instances.
--   
--   Note that argument order changed in v0.2.4
backpropWith :: Backprop a => (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> (b, b -> 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 just use a
--   tuple. However, this could potentially be more performant.
--   
--   For 3 and more arguments, consider using <a>backpropN</a>.
backprop2 :: (Backprop a, Backprop b, Backprop 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 :: (Backprop a, Backprop b, Backprop c) => (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (a, b)

-- | <a>backprop2</a>, but allows you to provide the gradient of the "final
--   result" with respect to the output of your function. See
--   <a>backpropWith</a> for more details.
--   
--   Note that argument order changed in v0.2.4
backpropWith2 :: (Backprop a, Backprop b) => (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) -> a -> b -> (c, c -> (a, b))

-- | <a>backprop</a> 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 giant tuple. However, this could potentially also be
--   more performant.
--   
--   A <tt><a>Rec</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 <tt>:&lt;</tt>
--   (cons) and <tt>Ø</tt> (nil).
--   
--   The <tt><a>AllConstrained</a> <a>Backprop</a> as</tt> in the
--   constraint says that every value in the type-level list <tt>as</tt>
--   must have a <a>Backprop</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>AllConstrained</a> <a>Backprop</a> as</tt> should be fulfilled
--   automatically.
backpropN :: (AllConstrained Backprop as, RecApplicative as, Backprop b) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> (b, Rec Identity 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 => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> b

-- | <a>gradBP</a> generalized to multiple inputs of different types. See
--   documentation for <a>backpropN</a> for more details.
gradBPN :: (AllConstrained Backprop as, RecApplicative as, Backprop b) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> Rec Identity as

-- | <a>backpropN</a>, but allows you to provide the gradient of the "final
--   result" with respect to the output of your function. See
--   <a>backpropWith</a> for more details.
--   
--   Note that argument order changed in v0.2.4.
backpropWithN :: (AllConstrained Backprop as, RecApplicative as) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Rec Identity as -> (b, b -> Rec Identity as)

-- | <a>evalBP</a> but with no arguments. Useful when everything is just
--   given through <a>constVar</a>.
evalBP0 :: (forall s. Reifies s W => BVar s a) -> a

-- | 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

-- | Shorter alias for <a>constVar</a>, inspired by the <i>ad</i> library.
auto :: a -> BVar s a

-- | Coerce a <a>BVar</a> contents. Useful for things like newtype
--   wrappers.
coerceVar :: Coercible a b => BVar s a -> BVar s b

-- | 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.
--   
--   If you have control of your data type definitions, consider using
--   <a>splitBV</a>, which lets you break out <a>BVar</a>s of values into
--   <a>BVar</a>s of their individual fields automatically without
--   requiring lenses.
--   
--   <b>NOTE</b>: Usage of <a>^^.</a> on many fields from the same item is
--   usually the main source of overhead in <i>backprop</i> code, if you
--   are looking to optimize your code. See
--   &lt;<a>https://backprop.jle.im/07-performance.html</a> this
--   performance guide&gt; for more information, and details on mitigating
--   this overhead.
--   
--   <b>WARNING</b>: Do not use with any lenses that operate "numerically"
--   on the contents (like <tt>multiplying</tt>).
(^^.) :: forall b a s. (Backprop b, Backprop a, Reifies s W) => 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:
--   
--   <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.
--   
--   Note that this does not incurr the performance overhead issues of
--   <a>viewVar</a> and <a>^^.</a>, and is fairly cheap.
(.~~) :: (Backprop a, Backprop b, Reifies s W) => Lens' b a -> BVar s a -> BVar s b -> BVar s b
infixl 8 .~~

-- | An infix version of <a>overVar</a>, meant to evoke parallels to
--   <a>%~</a> from lens.
--   
--   With normal values, you can set modify in a value with a lens:
--   
--   <pre>
--   x <a>&amp;</a> myLens <a>%~</a> <a>negate</a>
--   </pre>
--   
--   would "modify" a part of <tt>x :: b</tt>, specified by <tt>myLens ::
--   <a>Lens'</a> a b</tt>, using the function <tt>negate :: a -&gt;
--   a</tt>.
--   
--   <pre>
--   xVar <a>&amp;</a> myLens <a>%~~</a> <a>negate</a>
--   </pre>
--   
--   would "modify" 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>, using the function <tt>negate :: BVar s a -&gt;
--   BVar s </tt>. The result is a new (updated) value of type
--   <tt><a>BVar</a> s b</tt>.
--   
--   Is essentially a convenient wrapper over a <a>viewVar</a> followed by
--   a <a>setVar</a>.
(%~~) :: (Backprop a, Backprop b, Reifies s W) => Lens' b a -> (BVar s a -> BVar s a) -> BVar s b -> BVar s b
infixr 4 %~~

-- | 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.
--   
--   <b>NOTE</b>: Has the same potential of performance overhead issues as
--   <a>^^.</a>; see documentation of <a>^^.</a> for more details.
(^^?) :: forall b a s. (Backprop b, Backprop a, Reifies s W) => BVar s b -> Traversal' b a -> Maybe (BVar s a)
infixl 8 ^^?

-- | 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).
--   
--   <b>NOTE</b>: Has all of the performance overhead issues of
--   <a>sequenceVar</a>; see documentation for <a>sequenceVar</a> for more
--   information.
(^^..) :: forall b a s. (Backprop b, Backprop a, Reifies s W) => BVar s b -> Traversal' b a -> [BVar s a]

-- | An *UNSAFE* version of <a>^^?</a> and <a>previewVar</a> assuming that
--   the value is there.
--   
--   Is undefined if the <a>Traversal</a> hits no targets.
--   
--   Is essentially <a>^^?</a> with <a>fromJust</a>, or <a>^^..</a> with
--   <a>head</a>.
(^^?!) :: forall b a s. (Backprop b, Backprop a, Reifies s W) => BVar s b -> Traversal' b a -> BVar s a
infixl 8 ^^?!

-- | 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 <a>^^.</a> for more information, caveats, and
--   warnings.
viewVar :: forall b a s. (Backprop a, Backprop b, Reifies s W) => 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 <a>.~~</a> for more information.
setVar :: (Backprop a, Backprop b, Reifies s W) => Lens' b a -> BVar s a -> BVar s b -> BVar s b

-- | Using a <a>Lens'</a>, modify a value <i>inzide</i> a <a>BVar</a>.
--   Meant to evoke parallels to "over" from lens. See documentation for
--   <a>%~~</a> for more information.
overVar :: (Backprop a, Backprop b, Reifies s W) => Lens' b a -> (BVar s 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.
--   
--   <b>NOTE</b>: A potential source of performance overhead. If there are
--   &lt;math&gt; total elements, and you use &lt;math&gt; of them, then
--   there is an overhead cost on the order of &lt;math&gt;, with a
--   constant factor dependent on the cost of <a>add</a>. Should be
--   negligible for types with cheap <a>add</a> (like <a>Double</a>), but
--   may be costly for things like large matrices. See
--   &lt;<a>https://backprop.jle.im/07-performance.html</a> the performance
--   guide&gt; for for details.
sequenceVar :: (Traversable t, Backprop a, Reifies s W) => 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 does <b>not</b> suffer from the same performance
--   overhead issues as <a>sequenceVar</a>. <a>collectVar</a> is
--   &lt;math&gt;, with a very small constant factor that consistent for
--   all types. This reveals a general property of reverse-mode automatic
--   differentiation; "many to one" is cheap, but "one to many" is
--   expensive.
collectVar :: (Foldable t, Functor t, Backprop a, Reifies s W) => 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 <a>^^?</a> for more information, warnings, and
--   caveats.
previewVar :: forall b a s. (Backprop b, Backprop 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 <a>^^..</a> for more information, warnings, and
--   caveats.
toListOfVar :: forall b a s. (Backprop b, Backprop a, Reifies s W) => Traversal' b a -> BVar s b -> [BVar s a]

-- | Useful pattern for constructing and deconstructing <a>BVar</a>s of
--   two-tuples.

-- | Useful pattern for constructing and deconstructing <a>BVar</a>s
--   three-tuples.

-- | Convert the value inside a <a>BVar</a> using a given isomorphism.
--   Useful for things like constructors.
--   
--   If you have control of your data type definitions, consider using
--   <a>joinBV</a>, which lets you use your data type constructors
--   themselves to join together <a>BVar</a>s as their fields.
--   
--   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 :: (Backprop a, 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.
--   
--   If you have control of your data type definitions, consider using
--   <a>joinBV</a>, which lets you use your data type constructors
--   themselves to join together <a>BVar</a>s as their fields.
isoVar2 :: (Backprop a, Backprop b, 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 :: (Backprop a, Backprop b, Backprop c, 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.
--   
--   If you have control of your data type definitions, consider using
--   <a>joinBV</a>, which lets you use your data type constructors
--   themselves to join together <a>BVar</a>s as their fields.
isoVarN :: (AllConstrained Backprop as, RecApplicative as, Reifies s W) => (Rec Identity as -> b) -> (b -> Rec Identity as) -> Rec (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>Rec</a>.
liftOp :: (AllConstrained Backprop as, RecApplicative as, Reifies s W) => Op as b -> Rec (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 :: (Backprop a, Reifies s W) => 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 :: (Backprop a, Backprop b, Reifies s W) => 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 :: (Backprop a, Backprop b, Backprop c, Reifies s W) => Op '[a, b, c] d -> BVar s a -> BVar s b -> BVar s c -> BVar s d

-- | Split out a <a>BVar</a> of "higher-kinded data type", a la
--   <a>http://reasonablypolymorphic.com/blog/higher-kinded-data/</a>
--   
--   Lets you take <a>BVar</a> of a value into a separate <a>BVar</a> of
--   every field of that value.
--   
--   See <a>Numeric.Backprop#hkd</a> for a tutorial on usage.
--   
--   This will work with all data types made with a single constructor,
--   whose fields are all instances of <a>Backprop</a>, where the type
--   itself has an instance of <a>Backprop</a>. The type also must derive
--   <a>Generic</a>.
--   
--   Note that access using <a>splitBV</a> and pattern matching is slightly
--   slower than access using lenses (by about 10-20%).
--   
--   See also <a>BV</a>, pattern synonym version where the deconstructor is
--   exactly a view into <a>splitBV</a>.
--   
--   <b>NOTE</b>: Like <a>^^.</a> and <a>viewVar</a>, <a>splitBV</a> usage
--   could potentially be the main source of performance overhead in your
--   program. If your data type has &lt;math&gt; fields, and you use
--   <a>splitBV</a> to later use &lt;math&gt; of those fields, there is an
--   overhead cost on the order of &lt;math&gt;, with a constant factor
--   dependent on the cost of <a>add</a> for your original data type.
--   Should be negligible for types with cheap <a>add</a> (like
--   <a>Double</a>), but may be costly for things like large matrices. See
--   <a>the performance guide</a> for for details.
--   
--   However, there is some potential opportunities to re-write some core
--   library functionality that would allow <a>splitBV</a> to avoid all of
--   the significant performance overhead issues of <a>^^.</a>. Contact me
--   if you are interested in helping out!
splitBV :: (Generic (z f), Generic (z (BVar s)), BVGroup s as (Rep (z f)) (Rep (z (BVar s))), Backprop (z f), Backprop (Rep (z f) ()), AllConstrained Backprop as, RecApplicative as, Reifies s W) => BVar s (z f) -> z (BVar s)

-- | Assemble a <a>BVar</a> of "higher-kinded data type", a la
--   <a>http://reasonablypolymorphic.com/blog/higher-kinded-data/</a>
--   
--   It lets you take a <a>BVar</a> of every field of a value, and join
--   them into a <a>BVar</a> of that value.
--   
--   See <a>Numeric.Backprop#hkd</a> for a tutorial on usage.
--   
--   This will work with all data types made with a single constructor,
--   whose fields are all instances of <a>Backprop</a>, where the type
--   itself has an instance of <a>Backprop</a>.
--   
--   See also <a>BV</a>, a pattern synonym version where the constructor is
--   exactly <a>joinBV</a>.
--   
--   Note that <a>joinBV</a> does not suffer the major performance overhead
--   issues of <a>splitBV</a>. This is a general property of reverse-mode
--   automatic differentiation: "many to one" is cheap, but "one to many"
--   is expensive.
joinBV :: (Generic (z f), Generic (z (BVar s)), BVGroup s as (Rep (z f)) (Rep (z (BVar s))), Backprop (z f), Backprop (Rep (z f) ()), AllConstrained Backprop as, RecApplicative as, Reifies s W) => z (BVar s) -> BVar s (z f)

-- | Pattern synonym wrapping manual usage of <a>splitBV</a> and
--   <a>joinBV</a>. It is a pattern for a <tt><a>BVar</a> s (z f)</tt>
--   containing a <tt>z (<a>BVar</a> s)</tt>

-- | Helper class for generically "splitting" and "joining" <a>BVar</a>s
--   into constructors. See <a>splitBV</a> and <a>joinBV</a>.
--   
--   See <a>Numeric.Backprop#hkd</a> for a tutorial on how to use this.
--   
--   Instances should be available for types made with one constructor
--   whose fields are all instances of <a>Backprop</a>, with a
--   <a>Generic</a> instance.
class BVGroup s as i o | o -> i, i -> as

-- | 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>Rec</a> and 'Rec Identity'.
--   
--   To <i>use</i> an <a>Op</a> with the backprop library, see
--   <tt>liftOp</tt>, <tt>liftOp1</tt>, <tt>liftOp2</tt>, and
--   <tt>liftOp3</tt>.
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 :: Rec Identity as -> (a, a -> Rec Identity 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 -> Rec Identity as -> (a, a -> Rec Identity 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) RNil
--   (10, RNil)
--   </pre>
--   
--   For a constant <a>Op</a> that takes input and ignores it, see
--   <a>opConst</a> and <tt>opConst'</tt>.
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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (10, 0 :&amp; 0 :&amp; 0 :&amp; RNil)
--   </pre>
opConst :: forall as a. (AllConstrained Num as, RecApplicative 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

-- | Create an <a>Op</a> from a backpropagatable function. Can be useful
--   for "storing" an otherwise Rank-N backpropagatable function in order
--   to avoid impredicative types. But this is pretty uncommon, so this is
--   mostly just used for low-level internal situations.
--   
--   <pre>
--   <a>liftOp</a> . <a>bpOp</a> = <a>id</a>
--   <a>bpOp</a> . <a>liftOp</a> = <a>id</a>
--   </pre>
bpOp :: (AllConstrained Backprop as, RecApplicative as) => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) -> Op as 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 :&amp; 2 :&amp; 3 :&amp; RNil)
--   (1 :&amp; 2 :&amp; 3 :&amp; RNil, 1 :&amp; 1 :&amp; 1 :&amp; RNil)
--   </pre>
opTup :: Op as (Rec Identity 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 :: (Rec Identity as -> b) -> (b -> Rec Identity 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 :: (Rec Identity as -> b) -> Op as b

-- | A record is parameterized by a universe <tt>u</tt>, an interpretation
--   <tt>f</tt> and a list of rows <tt>rs</tt>. The labels or indices of
--   the record are given by inhabitants of the kind <tt>u</tt>; the type
--   of values at any label <tt>r :: u</tt> is given by its interpretation
--   <tt>f r :: *</tt>.
data Rec (a :: u -> *) (b :: [u]) :: forall u. () => u -> * -> [u] -> *
[RNil] :: Rec a ([] :: [u])
[:&] :: Rec a r : rs
class Reifies (s :: k) a | s -> a


-- | Provides "explicit" versions of all of the functions in
--   <a>Prelude.Backprop</a>. Instead of relying on a <a>Backprop</a>
--   instance, allows you to manually provide <a>zero</a>, <a>add</a>, and
--   <a>one</a> on a per-value basis.
--   
--   WARNING: API of this module can be considered only "semi-stable";
--   while the API of <a>Prelude.Backprop</a> and Prelude.Backprop.Num" are
--   kept consistent, some argument order changes might happen in this
--   module to reflect changes in underlying implementation.
module Prelude.Backprop.Explicit

-- | <a>sum</a>, but taking explicit <a>add</a> and <a>zero</a>.
sum :: (Foldable t, Functor t, Num a, Reifies s W) => AddFunc (t a) -> BVar s (t a) -> BVar s a

-- | <a>product</a>, but taking explicit <a>add</a> and <a>zero</a>.
product :: (Foldable t, Functor t, Fractional a, Reifies s W) => AddFunc (t a) -> BVar s (t a) -> BVar s a

-- | <a>length</a>, but taking explicit <a>add</a> and <a>zero</a>.
length :: (Foldable t, Num b, Reifies s W) => AddFunc (t a) -> ZeroFunc (t a) -> BVar s (t a) -> BVar s b

-- | <a>minimum</a>, but taking explicit <a>add</a> and <a>zero</a>.
minimum :: (Foldable t, Functor t, Ord a, Reifies s W) => AddFunc (t a) -> ZeroFunc a -> BVar s (t a) -> BVar s a

-- | <a>maximum</a>, but taking explicit <a>add</a> and <a>zero</a>.
maximum :: (Foldable t, Functor t, Ord a, Reifies s W) => AddFunc (t a) -> ZeroFunc a -> BVar s (t a) -> BVar s a

-- | <a>traverse</a>, but taking explicit <a>add</a> and <a>zero</a>.
traverse :: (Traversable t, Applicative f, Foldable f, Reifies s W) => AddFunc a -> AddFunc b -> AddFunc (t b) -> ZeroFunc a -> ZeroFunc b -> (BVar s a -> f (BVar s b)) -> BVar s (t a) -> BVar s (f (t b))

-- | <a>length</a>, but taking explicit <a>add</a> and <a>zero</a>.
toList :: (Traversable t, Reifies s W) => AddFunc a -> ZeroFunc a -> BVar s (t a) -> [BVar s a]

-- | <a>mapAccumL</a>, but taking explicit <a>add</a> and <a>zero</a>.
mapAccumL :: (Traversable t, Reifies s W) => AddFunc b -> AddFunc c -> ZeroFunc b -> ZeroFunc c -> (BVar s a -> BVar s b -> (BVar s a, BVar s c)) -> BVar s a -> BVar s (t b) -> (BVar s a, BVar s (t c))

-- | <a>mapAccumR</a>, but taking explicit <a>add</a> and <a>zero</a>.
mapAccumR :: (Traversable t, Reifies s W) => AddFunc b -> AddFunc c -> ZeroFunc b -> ZeroFunc c -> (BVar s a -> BVar s b -> (BVar s a, BVar s c)) -> BVar s a -> BVar s (t b) -> (BVar s a, BVar s (t c))

-- | <a>foldr</a>, but taking explicit <a>add</a> and <a>zero</a>.
foldr :: (Traversable t, Reifies s W) => AddFunc a -> ZeroFunc a -> (BVar s a -> BVar s b -> BVar s b) -> BVar s b -> BVar s (t a) -> BVar s b

-- | <a>foldl'</a>, but taking explicit <a>add</a> and <a>zero</a>.
foldl' :: (Traversable t, Reifies s W) => AddFunc a -> ZeroFunc a -> (BVar s b -> BVar s a -> BVar s b) -> BVar s b -> BVar s (t a) -> BVar s b

-- | <a>fmap</a>, but taking explicit <a>add</a> and <a>zero</a>.
fmap :: (Traversable f, Reifies s W) => AddFunc a -> AddFunc b -> ZeroFunc a -> ZeroFunc b -> (BVar s a -> BVar s b) -> BVar s (f a) -> BVar s (f b)

-- | <a>fmapConst</a>, but taking explicit <a>add</a> and <a>zero</a>.
fmapConst :: (Functor f, Foldable f, Reifies s W) => AddFunc (f a) -> AddFunc b -> ZeroFunc (f a) -> ZeroFunc b -> BVar s b -> BVar s (f a) -> BVar s (f b)

-- | <a>pure</a>, but taking explicit <a>add</a> and <a>zero</a>.
pure :: (Foldable t, Applicative t, Reifies s W) => AddFunc a -> ZeroFunc a -> BVar s a -> BVar s (t a)

-- | <a>liftA2</a>, but taking explicit <a>add</a> and <a>zero</a>.
liftA2 :: (Traversable f, Applicative f, Reifies s W) => AddFunc a -> AddFunc b -> AddFunc c -> ZeroFunc a -> ZeroFunc b -> ZeroFunc c -> (BVar s a -> BVar s b -> BVar s c) -> BVar s (f a) -> BVar s (f b) -> BVar s (f c)

-- | <a>liftA3</a>, but taking explicit <a>add</a> and <a>zero</a>.
liftA3 :: (Traversable f, Applicative f, Reifies s W) => AddFunc a -> AddFunc b -> AddFunc c -> AddFunc d -> ZeroFunc a -> ZeroFunc b -> ZeroFunc c -> ZeroFunc d -> (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)

-- | <a>fromIntegral</a>, but taking explicit <a>add</a> and <a>zero</a>.
fromIntegral :: (Integral a, Integral b, Reifies s W) => AddFunc a -> BVar s a -> BVar s b

-- | <a>realToFrac</a>, but taking explicit <a>add</a> and <a>zero</a>.
realToFrac :: (Fractional a, Real a, Fractional b, Real b, Reifies s W) => AddFunc a -> BVar s a -> BVar s b

-- | <a>round</a>, but taking explicit <a>add</a> and <a>zero</a>.
round :: (RealFrac a, Integral b, Reifies s W) => AddFunc a -> BVar s a -> BVar s b

-- | <a>fromIntegral'</a>, but taking explicit <a>add</a> and <a>zero</a>.
fromIntegral' :: (Integral a, RealFrac b, Reifies s W) => AddFunc a -> BVar s a -> BVar s b

-- | Coerce items inside a <a>BVar</a>.
coerce :: Coercible a b => BVar s a -> BVar s b


-- | Some lifted versions of common functions found in <tt>Prelude</tt> (or
--   <i>base</i> in general).
--   
--   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.
--   
--   See <a>Prelude.Backprop.Num</a> for a version with <a>Num</a>
--   constraints instead of <a>Backprop</a> constraints, and
--   <a>Prelude.Backprop.Explicit</a> for a version allowing you to provide
--   <a>zero</a>, <a>add</a>, and <a>one</a> explicitly.
module Prelude.Backprop

-- | Lifted <a>sum</a>. More efficient than going through <a>toList</a>.
sum :: (Foldable t, Functor t, Backprop (t a), Num a, Reifies s W) => BVar s (t a) -> BVar s a

-- | Lifted <a>product</a>. More efficient than going through
--   <a>toList</a>.
product :: (Foldable t, Functor t, Backprop (t a), Fractional a, Reifies s W) => BVar s (t a) -> BVar s a

-- | Lifted <a>length</a>. More efficient than going through <a>toList</a>.
length :: (Foldable t, Backprop (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. More efficient than going through <a>toList</a>.
minimum :: (Foldable t, Functor t, Backprop a, Ord a, Backprop (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. More efficient than going through <a>toList</a>.
maximum :: (Foldable t, Functor t, Backprop a, Ord a, Backprop (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.
traverse :: (Traversable t, Applicative f, Foldable f, Backprop a, Backprop b, Backprop (t b), Reifies s W) => (BVar s a -> f (BVar s b)) -> BVar s (t a) -> BVar s (f (t b))

-- | Lifted version of <a>toList</a>. Takes a <a>BVar</a> of a
--   <a>Traversable</a> of items and returns a list of <a>BVar</a>s for
--   each item.
--   
--   You can use this to implement "lifted" versions of <a>Foldable</a>
--   methods like <a>foldr</a>, <a>foldl'</a>, etc.; however, <a>sum</a>,
--   <a>product</a>, <a>length</a>, <a>minimum</a>, and <a>maximum</a> have
--   more efficient implementations than simply <tt><a>minimum</a> .
--   <a>toList</a>.</tt>
toList :: (Traversable t, Backprop a, Reifies s W) => BVar s (t a) -> [BVar s a]

-- | Lifted version of <a>mapAccumL</a>.
--   
--   Prior to v0.2.3, required a <a>Backprop</a> constraint on <tt>t
--   b</tt>.
mapAccumL :: (Traversable t, Backprop b, Backprop c, Reifies s W) => (BVar s a -> BVar s b -> (BVar s a, BVar s c)) -> BVar s a -> BVar s (t b) -> (BVar s a, BVar s (t c))

-- | Lifted version of <a>mapAccumR</a>.
--   
--   Prior to v0.2.3, required a <a>Backprop</a> constraint on <tt>t
--   b</tt>.
mapAccumR :: (Traversable t, Backprop b, Backprop c, Reifies s W) => (BVar s a -> BVar s b -> (BVar s a, BVar s c)) -> BVar s a -> BVar s (t b) -> (BVar s a, BVar s (t c))

-- | Lifed <a>foldr</a>. Essentially just <a>toList</a> composed with a
--   normal list <a>foldr</a>, and is only here for convenience.
foldr :: (Traversable t, Backprop a, Reifies s W) => (BVar s a -> BVar s b -> BVar s b) -> BVar s b -> BVar s (t a) -> BVar s b

-- | Lifed <a>foldl'</a>. Essentially just <a>toList</a> composed with a
--   normal list <a>foldl'</a>, and is only here for convenience.
foldl' :: (Traversable t, Backprop a, Reifies s W) => (BVar s b -> BVar s a -> BVar s b) -> BVar s b -> BVar s (t a) -> BVar s b

-- | Lifted <a>fmap</a>. Lifts backpropagatable functions to be
--   backpropagatable functions on <a>Traversable</a> <a>Functor</a>s.
fmap :: (Traversable f, Backprop a, Backprop b, Reifies s W) => (BVar s a -> BVar s b) -> BVar s (f a) -> BVar s (f b)

-- | Efficient version of <a>fmap</a> when used to "replace" all values in
--   a <a>Functor</a> value.
--   
--   <pre>
--   <a>fmapConst</a> x = <a>fmap</a> (<a>const</a> x)
--   </pre>
--   
--   but much more efficient.
fmapConst :: (Functor f, Foldable f, Backprop b, Backprop (f a), Reifies s W) => BVar s b -> BVar s (f a) -> BVar s (f b)

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

-- | Alias for <a>fmapConst</a>.
(<$) :: (Traversable f, Backprop b, Backprop (f a), Reifies s W) => BVar s b -> BVar s (f a) -> BVar s (f b)
infixl 4 <$

-- | Alias for <tt><tt>flip</tt> <a>fmapConst</a></tt>.
($>) :: (Traversable f, Backprop b, Backprop (f a), Reifies s W) => BVar s (f a) -> BVar s b -> BVar s (f b)
infixl 4 $>

-- | Lifted <a>pure</a>.
pure :: (Foldable t, Applicative t, Backprop 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.
liftA2 :: (Traversable f, Applicative f, Backprop a, Backprop b, Backprop 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.
liftA3 :: (Traversable f, Applicative f, Backprop a, Backprop b, Backprop c, Backprop 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)

-- | Lifted conversion between two <a>Integral</a> instances.
fromIntegral :: (Backprop a, Integral a, Integral b, Reifies s W) => BVar s a -> BVar s b

-- | Lifted conversion between two <a>Fractional</a> and <a>Real</a>
--   instances.
realToFrac :: (Backprop a, Fractional a, Real a, Fractional b, Real b, Reifies s W) => BVar s a -> BVar s b

-- | Lifted version of <a>round</a>.
--   
--   Gradient should technically diverge whenever the fractional part is
--   0.5, but does not do this for convenience reasons.
round :: (RealFrac a, Integral b, Reifies s W) => BVar s a -> BVar s b

-- | Lifted version of <a>fromIntegral</a>, defined to let you return
--   <a>RealFrac</a> instances as targets, instead of only other
--   <a>Integral</a>s. Essentially the opposite of <a>round</a>.
--   
--   The gradient should technically diverge whenever the fractional part
--   of the downstream gradient is 0.5, but does not do this for
--   convenience reasons.
fromIntegral' :: (Integral a, RealFrac b, Reifies s W) => BVar s a -> BVar s b

-- | Coerce items inside a <a>BVar</a>.
coerce :: Coercible a b => BVar s a -> BVar s b


-- | Provides the exact same API as <a>Prelude.Backprop</a>, except
--   requiring <a>Num</a> instances for all types involved instead of
--   <tt>Backprop</tt> instances.
module Prelude.Backprop.Num

-- | <a>sum</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
sum :: (Foldable t, Functor t, Num (t a), Num a, Reifies s W) => BVar s (t a) -> BVar s a

-- | <a>product</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
product :: (Foldable t, Functor t, Num (t a), Fractional a, Reifies s W) => BVar s (t a) -> BVar s a

-- | <a>length</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
length :: (Foldable t, Num (t a), Num b, Reifies s W) => BVar s (t a) -> BVar s b

-- | <a>minimum</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
minimum :: (Foldable t, Functor t, Num a, Ord a, Num (t a), Reifies s W) => BVar s (t a) -> BVar s a

-- | <a>maximum</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
maximum :: (Foldable t, Functor t, Num a, Ord a, Num (t a), Reifies s W) => BVar s (t a) -> BVar s a

-- | <a>traverse</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   See <a>vector-sized</a> for a fixed-length vector type with a very
--   appropriate <a>Num</a> instance!
traverse :: (Traversable t, Applicative f, Foldable f, Num a, Num b, Num (t b), Reifies s W) => (BVar s a -> f (BVar s b)) -> BVar s (t a) -> BVar s (f (t b))

-- | <a>toList</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
toList :: (Traversable t, Num a, Reifies s W) => BVar s (t a) -> [BVar s a]

-- | <a>mapAccumL</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Prior to v0.2.3, required a <a>Num</a> constraint on <tt>t b</tt>.
mapAccumL :: (Traversable t, Num b, Num c, Reifies s W) => (BVar s a -> BVar s b -> (BVar s a, BVar s c)) -> BVar s a -> BVar s (t b) -> (BVar s a, BVar s (t c))

-- | <a>mapAccumR</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
--   
--   Prior to v0.2.3, required a <a>Num</a> constraint on <tt>t b</tt>.
mapAccumR :: (Traversable t, Num b, Num c, Reifies s W) => (BVar s a -> BVar s b -> (BVar s a, BVar s c)) -> BVar s a -> BVar s (t b) -> (BVar s a, BVar s (t c))

-- | <a>foldr</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
foldr :: (Traversable t, Num a, Reifies s W) => (BVar s a -> BVar s b -> BVar s b) -> BVar s b -> BVar s (t a) -> BVar s b

-- | <a>foldl'</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
foldl' :: (Traversable t, Num a, Reifies s W) => (BVar s b -> BVar s a -> BVar s b) -> BVar s b -> BVar s (t a) -> BVar s b

-- | <a>fmap</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
fmap :: (Traversable f, Num a, Num b, Reifies s W) => (BVar s a -> BVar s b) -> BVar s (f a) -> BVar s (f b)

-- | <a>fmapConst</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
fmapConst :: (Functor f, Foldable f, Num b, Num (f a), Reifies s W) => BVar s b -> BVar s (f a) -> BVar s (f b)

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

-- | Alias for <a>fmapConst</a>.
(<$) :: (Functor f, Foldable f, Num b, Num (f a), Reifies s W) => BVar s b -> BVar s (f a) -> BVar s (f b)
infixl 4 <$

-- | Alias for <tt><tt>flip</tt> <a>fmapConst</a></tt>.
($>) :: (Functor f, Foldable f, Num b, Num (f a), Reifies s W) => BVar s (f a) -> BVar s b -> BVar s (f b)
infixl 4 $>

-- | <a>pure</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
pure :: (Foldable t, Applicative t, Num a, Reifies s W) => BVar s a -> BVar s (t a)

-- | <a>liftA2</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
liftA2 :: (Traversable f, Applicative f, Num a, Num b, Num 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)

-- | <a>liftA3</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
liftA3 :: (Traversable f, Applicative f, Num a, Num b, Num c, Num 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)

-- | <a>fromIntegral</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
fromIntegral :: (Integral a, Integral b, Reifies s W) => BVar s a -> BVar s b

-- | <a>realToFrac</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
realToFrac :: (Fractional a, Real a, Fractional b, Real b, Reifies s W) => BVar s a -> BVar s b

-- | <a>round</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
round :: (RealFrac a, Integral b, Reifies s W) => BVar s a -> BVar s b

-- | <a>fromIntegral'</a>, but with <a>Num</a> constraints instead of
--   <tt>Backprop</tt> constraints.
fromIntegral' :: (Integral a, RealFrac b, Reifies s W) => BVar s a -> BVar s b

-- | Coerce items inside a <a>BVar</a>.
coerce :: Coercible a b => BVar s a -> BVar s b
