{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_HADDOCK not-home #-}

-- |
-- Module      : Prelude.Backprop.Explicit
-- Copyright   : (c) Justin Le 2023
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
--
-- Provides "explicit" versions of all of the functions in
-- "Prelude.Backprop".  Instead of relying on a 'Backprop' instance, allows
-- you to manually provide 'zero', 'add', and 'one' on a per-value basis.
--
-- WARNING: API of this module can be considered only "semi-stable"; while
-- the API of "Prelude.Backprop" and Prelude.Backprop.Num" are kept
-- consistent, some argument order changes might happen in this module to
-- reflect changes in underlying implementation.
--
-- @since 0.2.0.0
module Prelude.Backprop.Explicit (
  -- * Foldable and Traversable
  sum,
  product,
  length,
  minimum,
  maximum,
  traverse,
  toList,
  mapAccumL,
  mapAccumR,
  foldr,
  foldl',

  -- * Functor and Applicative
  fmap,
  fmapConst,
  pure,
  liftA2,
  liftA3,

  -- * Numeric
  fromIntegral,
  realToFrac,
  round,
  fromIntegral',

  -- * Misc
  coerce,
) where

import qualified Control.Applicative as P
import Data.Bifunctor
import qualified Data.Coerce as C
import qualified Data.Foldable as P
import qualified Data.Traversable as P
import Numeric.Backprop.Explicit
import Prelude (
  Applicative,
  Eq (..),
  Foldable,
  Fractional (..),
  Functor,
  Num (..),
  Ord (..),
  Traversable,
  ($),
  (.),
 )
import qualified Prelude as P

-- | 'Prelude.Backprop.sum', but taking explicit 'add' and 'zero'.
sum ::
  (Foldable t, Functor t, Num a, Reifies s W) =>
  AddFunc (t a) ->
  BVar s (t a) ->
  BVar s a
sum :: forall (t :: * -> *) a s.
(Foldable t, Functor t, Num a, Reifies s W) =>
AddFunc (t a) -> BVar s (t a) -> BVar s a
sum AddFunc (t a)
af = AddFunc (t a) -> Op '[t a] a -> BVar s (t a) -> BVar s a
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc (t a)
af (Op '[t a] a -> BVar s (t a) -> BVar s a)
-> ((t a -> (a, a -> t a)) -> Op '[t a] a)
-> (t a -> (a, a -> t a))
-> BVar s (t a)
-> BVar s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t a -> (a, a -> t a)) -> Op '[t a] a
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 ((t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a)
-> (t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a
forall a b. (a -> b) -> a -> b
$ \t a
xs ->
  ( t a -> a
forall a. Num a => t a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
P.sum t a
xs
  , (a -> t a -> t a
forall a b. a -> t b -> t a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
P.<$ t a
xs)
  )
{-# INLINE sum #-}

-- | 'Prelude.Backprop.pure', but taking explicit 'add' and 'zero'.
pure ::
  (Foldable t, Applicative t, Reifies s W) =>
  AddFunc a ->
  ZeroFunc a ->
  BVar s a ->
  BVar s (t a)
pure :: forall (t :: * -> *) s a.
(Foldable t, Applicative t, Reifies s W) =>
AddFunc a -> ZeroFunc a -> BVar s a -> BVar s (t a)
pure AddFunc a
af ZeroFunc a
zfa = AddFunc a -> Op '[a] (t a) -> BVar s a -> BVar s (t a)
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc a
af (Op '[a] (t a) -> BVar s a -> BVar s (t a))
-> ((a -> (t a, t a -> a)) -> Op '[a] (t a))
-> (a -> (t a, t a -> a))
-> BVar s a
-> BVar s (t a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (t a, t a -> a)) -> Op '[a] (t a)
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 ((a -> (t a, t a -> a)) -> BVar s a -> BVar s (t a))
-> (a -> (t a, t a -> a)) -> BVar s a -> BVar s (t a)
forall a b. (a -> b) -> a -> b
$ \a
x ->
  ( a -> t a
forall a. a -> t a
forall (f :: * -> *) a. Applicative f => a -> f a
P.pure a
x
  , \t a
d -> case t a -> [a]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
P.toList t a
d of
      [] -> ZeroFunc a -> a -> a
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc a
zfa a
x
      a
e : [a]
es -> (a -> a -> a) -> a -> [a] -> a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
P.foldl' (AddFunc a -> a -> a -> a
forall a. AddFunc a -> a -> a -> a
runAF AddFunc a
af) a
e [a]
es
  )
{-# INLINE pure #-}

-- | 'Prelude.Backprop.product', but taking explicit 'add' and 'zero'.
product ::
  (Foldable t, Functor t, Fractional a, Reifies s W) =>
  AddFunc (t a) ->
  BVar s (t a) ->
  BVar s a
product :: forall (t :: * -> *) a s.
(Foldable t, Functor t, Fractional a, Reifies s W) =>
AddFunc (t a) -> BVar s (t a) -> BVar s a
product AddFunc (t a)
af = AddFunc (t a) -> Op '[t a] a -> BVar s (t a) -> BVar s a
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc (t a)
af (Op '[t a] a -> BVar s (t a) -> BVar s a)
-> ((t a -> (a, a -> t a)) -> Op '[t a] a)
-> (t a -> (a, a -> t a))
-> BVar s (t a)
-> BVar s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t a -> (a, a -> t a)) -> Op '[t a] a
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 ((t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a)
-> (t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a
forall a b. (a -> b) -> a -> b
$ \t a
xs ->
  let p :: a
p = t a -> a
forall a. Num a => t a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
P.product t a
xs
   in ( a
p
      , \a
d -> (\a
x -> a
p a -> a -> a
forall a. Num a => a -> a -> a
* a
d a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
x) (a -> a) -> t a -> t a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.<$> t a
xs
      )
{-# INLINE product #-}

-- | 'Prelude.Backprop.length', but taking explicit 'add' and 'zero'.
length ::
  (Foldable t, Num b, Reifies s W) =>
  AddFunc (t a) ->
  ZeroFunc (t a) ->
  BVar s (t a) ->
  BVar s b
length :: forall (t :: * -> *) b s a.
(Foldable t, Num b, Reifies s W) =>
AddFunc (t a) -> ZeroFunc (t a) -> BVar s (t a) -> BVar s b
length AddFunc (t a)
af ZeroFunc (t a)
zfa = AddFunc (t a) -> Op '[t a] b -> BVar s (t a) -> BVar s b
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc (t a)
af (Op '[t a] b -> BVar s (t a) -> BVar s b)
-> ((t a -> (b, b -> t a)) -> Op '[t a] b)
-> (t a -> (b, b -> t a))
-> BVar s (t a)
-> BVar s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t a -> (b, b -> t a)) -> Op '[t a] b
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 ((t a -> (b, b -> t a)) -> BVar s (t a) -> BVar s b)
-> (t a -> (b, b -> t a)) -> BVar s (t a) -> BVar s b
forall a b. (a -> b) -> a -> b
$ \t a
xs ->
  ( Int -> b
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral (t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
P.length t a
xs)
  , t a -> b -> t a
forall a b. a -> b -> a
P.const (ZeroFunc (t a) -> t a -> t a
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc (t a)
zfa t a
xs)
  )
{-# INLINE length #-}

-- | 'Prelude.Backprop.minimum', but taking explicit 'add' and 'zero'.
minimum ::
  (Foldable t, Functor t, Ord a, Reifies s W) =>
  AddFunc (t a) ->
  ZeroFunc a ->
  BVar s (t a) ->
  BVar s a
minimum :: forall (t :: * -> *) a s.
(Foldable t, Functor t, Ord a, Reifies s W) =>
AddFunc (t a) -> ZeroFunc a -> BVar s (t a) -> BVar s a
minimum AddFunc (t a)
af ZeroFunc a
zf = AddFunc (t a) -> Op '[t a] a -> BVar s (t a) -> BVar s a
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc (t a)
af (Op '[t a] a -> BVar s (t a) -> BVar s a)
-> ((t a -> (a, a -> t a)) -> Op '[t a] a)
-> (t a -> (a, a -> t a))
-> BVar s (t a)
-> BVar s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t a -> (a, a -> t a)) -> Op '[t a] a
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 ((t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a)
-> (t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a
forall a b. (a -> b) -> a -> b
$ \t a
xs ->
  let m :: a
m = t a -> a
forall a. Ord a => t a -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
P.minimum t a
xs
   in ( a
m
      , \a
d -> (\a
x -> if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
m then a
d else ZeroFunc a -> a -> a
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc a
zf a
x) (a -> a) -> t a -> t a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.<$> t a
xs
      )
{-# INLINE minimum #-}

-- | 'Prelude.Backprop.maximum', but taking explicit 'add' and 'zero'.
maximum ::
  (Foldable t, Functor t, Ord a, Reifies s W) =>
  AddFunc (t a) ->
  ZeroFunc a ->
  BVar s (t a) ->
  BVar s a
maximum :: forall (t :: * -> *) a s.
(Foldable t, Functor t, Ord a, Reifies s W) =>
AddFunc (t a) -> ZeroFunc a -> BVar s (t a) -> BVar s a
maximum AddFunc (t a)
af ZeroFunc a
zf = AddFunc (t a) -> Op '[t a] a -> BVar s (t a) -> BVar s a
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc (t a)
af (Op '[t a] a -> BVar s (t a) -> BVar s a)
-> ((t a -> (a, a -> t a)) -> Op '[t a] a)
-> (t a -> (a, a -> t a))
-> BVar s (t a)
-> BVar s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t a -> (a, a -> t a)) -> Op '[t a] a
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 ((t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a)
-> (t a -> (a, a -> t a)) -> BVar s (t a) -> BVar s a
forall a b. (a -> b) -> a -> b
$ \t a
xs ->
  let m :: a
m = t a -> a
forall a. Ord a => t a -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
P.maximum t a
xs
   in ( a
m
      , \a
d -> (\a
x -> if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
m then a
d else ZeroFunc a -> a -> a
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc a
zf a
x) (a -> a) -> t a -> t a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.<$> t a
xs
      )
{-# INLINE maximum #-}

-- | 'Prelude.Backprop.foldr', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.3.0
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
foldr :: forall (t :: * -> *) s a b.
(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
foldr AddFunc a
af ZeroFunc a
z BVar s a -> BVar s b -> BVar s b
f BVar s b
x = (BVar s a -> BVar s b -> BVar s b)
-> BVar s b -> [BVar s a] -> BVar s b
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
P.foldr BVar s a -> BVar s b -> BVar s b
f BVar s b
x ([BVar s a] -> BVar s b)
-> (BVar s (t a) -> [BVar s a]) -> BVar s (t a) -> BVar s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc a -> ZeroFunc a -> BVar s (t a) -> [BVar s a]
forall (t :: * -> *) s a.
(Traversable t, Reifies s W) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> [BVar s a]
toList AddFunc a
af ZeroFunc a
z
{-# INLINE foldr #-}

-- | 'Prelude.Backprop.foldl'', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.3.0
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
foldl' :: forall (t :: * -> *) s a b.
(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
foldl' AddFunc a
af ZeroFunc a
z BVar s b -> BVar s a -> BVar s b
f BVar s b
x = (BVar s b -> BVar s a -> BVar s b)
-> BVar s b -> [BVar s a] -> BVar s b
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
P.foldl' BVar s b -> BVar s a -> BVar s b
f BVar s b
x ([BVar s a] -> BVar s b)
-> (BVar s (t a) -> [BVar s a]) -> BVar s (t a) -> BVar s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc a -> ZeroFunc a -> BVar s (t a) -> [BVar s a]
forall (t :: * -> *) s a.
(Traversable t, Reifies s W) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> [BVar s a]
toList AddFunc a
af ZeroFunc a
z
{-# INLINE foldl' #-}

-- | 'Prelude.Backprop.fmap', but taking explicit 'add' and 'zero'.
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)
fmap :: forall (f :: * -> *) s a b.
(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)
fmap AddFunc a
afa AddFunc b
afb ZeroFunc a
zfa ZeroFunc b
zfb BVar s a -> BVar s b
f = AddFunc b -> ZeroFunc b -> f (BVar s b) -> BVar s (f b)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc b
afb ZeroFunc b
zfb (f (BVar s b) -> BVar s (f b))
-> (BVar s (f a) -> f (BVar s b)) -> BVar s (f a) -> BVar s (f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BVar s a -> BVar s b) -> f (BVar s a) -> f (BVar s b)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.fmap BVar s a -> BVar s b
f (f (BVar s a) -> f (BVar s b))
-> (BVar s (f a) -> f (BVar s a)) -> BVar s (f a) -> f (BVar s b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc a -> ZeroFunc a -> BVar s (f a) -> f (BVar s a)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc a
afa ZeroFunc a
zfa
{-# INLINE fmap #-}

-- | 'Prelude.Backprop.fmapConst', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.4.0
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)
fmapConst :: forall (f :: * -> *) s a b.
(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)
fmapConst AddFunc (f a)
afa AddFunc b
afb ZeroFunc (f a)
zfa ZeroFunc b
zfb = AddFunc b
-> AddFunc (f a)
-> Op '[b, f a] (f b)
-> BVar s b
-> BVar s (f a)
-> BVar s (f b)
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
liftOp2 AddFunc b
afb AddFunc (f a)
afa (Op '[b, f a] (f b) -> BVar s b -> BVar s (f a) -> BVar s (f b))
-> ((b -> f a -> (f b, f b -> (b, f a))) -> Op '[b, f a] (f b))
-> (b -> f a -> (f b, f b -> (b, f a)))
-> BVar s b
-> BVar s (f a)
-> BVar s (f b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> f a -> (f b, f b -> (b, f a))) -> Op '[b, f a] (f b)
forall a b c. (a -> b -> (c, c -> (a, b))) -> Op '[a, b] c
op2 ((b -> f a -> (f b, f b -> (b, f a)))
 -> BVar s b -> BVar s (f a) -> BVar s (f b))
-> (b -> f a -> (f b, f b -> (b, f a)))
-> BVar s b
-> BVar s (f a)
-> BVar s (f b)
forall a b. (a -> b) -> a -> b
$ \b
x f a
xs ->
  ( b
x b -> f a -> f b
forall a b. a -> f b -> f a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
P.<$ f a
xs
  , \f b
d ->
      ( case f b -> [b]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
P.toList f b
d of
          [] -> ZeroFunc b -> b -> b
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc b
zfb b
x
          b
e : [b]
es -> (b -> b -> b) -> b -> [b] -> b
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
P.foldl' (AddFunc b -> b -> b -> b
forall a. AddFunc a -> a -> a -> a
runAF AddFunc b
afb) b
e [b]
es
      , ZeroFunc (f a) -> f a -> f a
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc (f a)
zfa f a
xs
      )
  )
{-# INLINE fmapConst #-}

-- | 'Prelude.Backprop.traverse', but taking explicit 'add' and 'zero'.
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))
traverse :: forall (t :: * -> *) (f :: * -> *) s a b.
(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))
traverse AddFunc a
afa AddFunc b
afb AddFunc (t b)
aftb ZeroFunc a
zfa ZeroFunc b
zfb BVar s a -> f (BVar s b)
f =
  AddFunc (t b)
-> ZeroFunc (t b) -> f (BVar s (t b)) -> BVar s (f (t b))
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc (t b)
aftb ZeroFunc (t b)
zftb
    (f (BVar s (t b)) -> BVar s (f (t b)))
-> (BVar s (t a) -> f (BVar s (t b)))
-> BVar s (t a)
-> BVar s (f (t b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t (BVar s b) -> BVar s (t b))
-> f (t (BVar s b)) -> f (BVar s (t b))
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.fmap (AddFunc b -> ZeroFunc b -> t (BVar s b) -> BVar s (t b)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc b
afb ZeroFunc b
zfb)
    (f (t (BVar s b)) -> f (BVar s (t b)))
-> (BVar s (t a) -> f (t (BVar s b)))
-> BVar s (t a)
-> f (BVar s (t b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BVar s a -> f (BVar s b)) -> t (BVar s a) -> f (t (BVar s b))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> t a -> f (t b)
P.traverse BVar s a -> f (BVar s b)
f
    (t (BVar s a) -> f (t (BVar s b)))
-> (BVar s (t a) -> t (BVar s a))
-> BVar s (t a)
-> f (t (BVar s b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc a
afa ZeroFunc a
zfa
  where
    zftb :: ZeroFunc (t b)
zftb = (t b -> t b) -> ZeroFunc (t b)
forall a. (a -> a) -> ZeroFunc a
ZF ((t b -> t b) -> ZeroFunc (t b)) -> (t b -> t b) -> ZeroFunc (t b)
forall a b. (a -> b) -> a -> b
$ (b -> b) -> t b -> t b
forall a b. (a -> b) -> t a -> t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.fmap (ZeroFunc b -> b -> b
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc b
zfb)
    {-# INLINE zftb #-}
{-# INLINE traverse #-}

-- | 'Prelude.Backprop.liftA2', but taking explicit 'add' and 'zero'.
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)
liftA2 :: forall (f :: * -> *) s a b c.
(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)
liftA2 AddFunc a
afa AddFunc b
afb AddFunc c
afc ZeroFunc a
zfa ZeroFunc b
zfb ZeroFunc c
zfc BVar s a -> BVar s b -> BVar s c
f BVar s (f a)
x BVar s (f b)
y =
  AddFunc c -> ZeroFunc c -> f (BVar s c) -> BVar s (f c)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc c
afc ZeroFunc c
zfc (f (BVar s c) -> BVar s (f c)) -> f (BVar s c) -> BVar s (f c)
forall a b. (a -> b) -> a -> b
$
    BVar s a -> BVar s b -> BVar s c
f
      (BVar s a -> BVar s b -> BVar s c)
-> f (BVar s a) -> f (BVar s b -> BVar s c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.<$> AddFunc a -> ZeroFunc a -> BVar s (f a) -> f (BVar s a)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc a
afa ZeroFunc a
zfa BVar s (f a)
x
      f (BVar s b -> BVar s c) -> f (BVar s b) -> f (BVar s c)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
P.<*> AddFunc b -> ZeroFunc b -> BVar s (f b) -> f (BVar s b)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc b
afb ZeroFunc b
zfb BVar s (f b)
y
{-# INLINE liftA2 #-}

-- | 'Prelude.Backprop.liftA3', but taking explicit 'add' and 'zero'.
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)
liftA3 :: forall (f :: * -> *) s a b c d.
(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)
liftA3 AddFunc a
afa AddFunc b
afb AddFunc c
afc AddFunc d
afd ZeroFunc a
zfa ZeroFunc b
zfb ZeroFunc c
zfc ZeroFunc d
zfd BVar s a -> BVar s b -> BVar s c -> BVar s d
f BVar s (f a)
x BVar s (f b)
y BVar s (f c)
z =
  AddFunc d -> ZeroFunc d -> f (BVar s d) -> BVar s (f d)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc d
afd ZeroFunc d
zfd (f (BVar s d) -> BVar s (f d)) -> f (BVar s d) -> BVar s (f d)
forall a b. (a -> b) -> a -> b
$
    BVar s a -> BVar s b -> BVar s c -> BVar s d
f
      (BVar s a -> BVar s b -> BVar s c -> BVar s d)
-> f (BVar s a) -> f (BVar s b -> BVar s c -> BVar s d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.<$> AddFunc a -> ZeroFunc a -> BVar s (f a) -> f (BVar s a)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc a
afa ZeroFunc a
zfa BVar s (f a)
x
      f (BVar s b -> BVar s c -> BVar s d)
-> f (BVar s b) -> f (BVar s c -> BVar s d)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
P.<*> AddFunc b -> ZeroFunc b -> BVar s (f b) -> f (BVar s b)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc b
afb ZeroFunc b
zfb BVar s (f b)
y
      f (BVar s c -> BVar s d) -> f (BVar s c) -> f (BVar s d)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
P.<*> AddFunc c -> ZeroFunc c -> BVar s (f c) -> f (BVar s c)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc c
afc ZeroFunc c
zfc BVar s (f c)
z
{-# INLINE liftA3 #-}

-- | Coerce items inside a 'BVar'.
coerce :: C.Coercible a b => BVar s a -> BVar s b
coerce :: forall a b s. Coercible a b => BVar s a -> BVar s b
coerce = BVar s a -> BVar s b
forall a b s. Coercible a b => BVar s a -> BVar s b
coerceVar
{-# INLINE coerce #-}

-- | 'Prelude.Backprop.fromIntegral', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.1.0
fromIntegral ::
  (P.Integral a, P.Integral b, Reifies s W) =>
  AddFunc a ->
  BVar s a ->
  BVar s b
fromIntegral :: forall a b s.
(Integral a, Integral b, Reifies s W) =>
AddFunc a -> BVar s a -> BVar s b
fromIntegral AddFunc a
af = AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
forall s a b.
Reifies s W =>
AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
isoVar AddFunc a
af a -> b
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral b -> a
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
{-# INLINE fromIntegral #-}

-- | 'Prelude.Backprop.realToFrac', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.1.0
realToFrac ::
  (Fractional a, P.Real a, Fractional b, P.Real b, Reifies s W) =>
  AddFunc a ->
  BVar s a ->
  BVar s b
realToFrac :: forall a b s.
(Fractional a, Real a, Fractional b, Real b, Reifies s W) =>
AddFunc a -> BVar s a -> BVar s b
realToFrac AddFunc a
af = AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
forall s a b.
Reifies s W =>
AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
isoVar AddFunc a
af a -> b
forall a b. (Real a, Fractional b) => a -> b
P.realToFrac b -> a
forall a b. (Real a, Fractional b) => a -> b
P.realToFrac
{-# INLINE realToFrac #-}

-- | 'Prelude.Backprop.round', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.3.0
round ::
  (P.RealFrac a, P.Integral b, Reifies s W) =>
  AddFunc a ->
  BVar s a ->
  BVar s b
round :: forall a b s.
(RealFrac a, Integral b, Reifies s W) =>
AddFunc a -> BVar s a -> BVar s b
round AddFunc a
af = AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
forall s a b.
Reifies s W =>
AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
isoVar AddFunc a
af a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
P.round b -> a
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral
{-# INLINE round #-}

-- | 'Prelude.Backprop.fromIntegral'', but taking explicit 'add' and
-- 'zero'.
--
-- @since 0.2.3.0
fromIntegral' ::
  (P.Integral a, P.RealFrac b, Reifies s W) =>
  AddFunc a ->
  BVar s a ->
  BVar s b
fromIntegral' :: forall a b s.
(Integral a, RealFrac b, Reifies s W) =>
AddFunc a -> BVar s a -> BVar s b
fromIntegral' AddFunc a
af = AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
forall s a b.
Reifies s W =>
AddFunc a -> (a -> b) -> (b -> a) -> BVar s a -> BVar s b
isoVar AddFunc a
af a -> b
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral b -> a
forall b. Integral b => b -> b
forall a b. (RealFrac a, Integral b) => a -> b
P.round
{-# INLINE fromIntegral' #-}

-- | 'Prelude.Backprop.length', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.2.0
toList ::
  (Traversable t, Reifies s W) =>
  AddFunc a ->
  ZeroFunc a ->
  BVar s (t a) ->
  [BVar s a]
toList :: forall (t :: * -> *) s a.
(Traversable t, Reifies s W) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> [BVar s a]
toList AddFunc a
af ZeroFunc a
z = AddFunc a
-> ZeroFunc (t a)
-> Traversal' (t a) a
-> BVar s (t a)
-> [BVar s a]
forall b a s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Traversal' b a -> BVar s b -> [BVar s a]
toListOfVar AddFunc a
af ((t a -> t a) -> ZeroFunc (t a)
forall a. (a -> a) -> ZeroFunc a
ZF ((a -> a) -> t a -> t a
forall a b. (a -> b) -> t a -> t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
P.fmap (ZeroFunc a -> a -> a
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc a
z))) (a -> f a) -> t a -> f (t a)
Traversal' (t a) a
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> t a -> f (t b)
P.traverse
{-# INLINE toList #-}

-- | 'Prelude.Backprop.mapAccumL', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.2.0
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))
mapAccumL :: forall (t :: * -> *) s b c a.
(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))
mapAccumL AddFunc b
afb AddFunc c
afc ZeroFunc b
zfb ZeroFunc c
zfc BVar s a -> BVar s b -> (BVar s a, BVar s c)
f BVar s a
s =
  (t (BVar s c) -> BVar s (t c))
-> (BVar s a, t (BVar s c)) -> (BVar s a, BVar s (t c))
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (AddFunc c -> ZeroFunc c -> t (BVar s c) -> BVar s (t c)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc c
afc ZeroFunc c
zfc)
    ((BVar s a, t (BVar s c)) -> (BVar s a, BVar s (t c)))
-> (BVar s (t b) -> (BVar s a, t (BVar s c)))
-> BVar s (t b)
-> (BVar s a, BVar s (t c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BVar s a -> BVar s b -> (BVar s a, BVar s c))
-> BVar s a -> t (BVar s b) -> (BVar s a, t (BVar s c))
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
P.mapAccumL BVar s a -> BVar s b -> (BVar s a, BVar s c)
f BVar s a
s
    (t (BVar s b) -> (BVar s a, t (BVar s c)))
-> (BVar s (t b) -> t (BVar s b))
-> BVar s (t b)
-> (BVar s a, t (BVar s c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc b -> ZeroFunc b -> BVar s (t b) -> t (BVar s b)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc b
afb ZeroFunc b
zfb
{-# INLINE mapAccumL #-}

-- | 'Prelude.Backprop.mapAccumR', but taking explicit 'add' and 'zero'.
--
-- @since 0.2.2.0
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))
mapAccumR :: forall (t :: * -> *) s b c a.
(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))
mapAccumR AddFunc b
afb AddFunc c
afc ZeroFunc b
zfb ZeroFunc c
zfc BVar s a -> BVar s b -> (BVar s a, BVar s c)
f BVar s a
s =
  (t (BVar s c) -> BVar s (t c))
-> (BVar s a, t (BVar s c)) -> (BVar s a, BVar s (t c))
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (AddFunc c -> ZeroFunc c -> t (BVar s c) -> BVar s (t c)
forall (t :: * -> *) a s.
(Reifies s W, Foldable t, Functor t) =>
AddFunc a -> ZeroFunc a -> t (BVar s a) -> BVar s (t a)
collectVar AddFunc c
afc ZeroFunc c
zfc)
    ((BVar s a, t (BVar s c)) -> (BVar s a, BVar s (t c)))
-> (BVar s (t b) -> (BVar s a, t (BVar s c)))
-> BVar s (t b)
-> (BVar s a, BVar s (t c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BVar s a -> BVar s b -> (BVar s a, BVar s c))
-> BVar s a -> t (BVar s b) -> (BVar s a, t (BVar s c))
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
P.mapAccumR BVar s a -> BVar s b -> (BVar s a, BVar s c)
f BVar s a
s
    (t (BVar s b) -> (BVar s a, t (BVar s c)))
-> (BVar s (t b) -> t (BVar s b))
-> BVar s (t b)
-> (BVar s a, t (BVar s c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc b -> ZeroFunc b -> BVar s (t b) -> t (BVar s b)
forall (t :: * -> *) a s.
(Reifies s W, Traversable t) =>
AddFunc a -> ZeroFunc a -> BVar s (t a) -> t (BVar s a)
sequenceVar AddFunc b
afb ZeroFunc b
zfb
{-# INLINE mapAccumR #-}