{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_HADDOCK not-home #-}

-- |
-- Module      : Numeric.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
-- "Numeric.Backprop".  Instead of relying on a 'Backprop' instance, allows
-- you to manually provide 'zero', 'add', and 'one' on a per-value basis.
--
-- It is recommended you use "Numeric.Backprop" or "Numeric.Backprop.Num"
-- instead, unless your type has no 'Num' instance, or you else you want to
-- avoid defining orphan 'Backprop' instances for external types.  Can also
-- be useful if mixing and matching styles.
--
-- See "Numeric.Backprop" for fuller documentation on using these
-- functions.
--
-- WARNING: API of this module can be considered only "semi-stable"; while
-- the API of "Numeric.Backprop" and "Numeric.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 Numeric.Backprop.Explicit (
  -- * Types
  BVar,
  W,
  Backprop (..),
  ABP (..),
  NumBP (..),

  -- * Explicit 'zero', 'add', and 'one'
  ZeroFunc (..),
  zfNum,
  zfNums,
  zeroFunc,
  zeroFuncs,
  zfFunctor,
  AddFunc (..),
  afNum,
  afNums,
  addFunc,
  addFuncs,
  OneFunc (..),
  ofNum,
  ofNums,
  oneFunc,
  oneFuncs,
  ofFunctor,

  -- * Running
  backprop,
  evalBP,
  gradBP,
  backpropWith,

  -- ** Multiple inputs
  evalBP0,
  backprop2,
  evalBP2,
  gradBP2,
  backpropWith2,
  backpropN,
  evalBPN,
  gradBPN,
  backpropWithN,
  RPureConstrained,

  -- * Manipulating 'BVar'
  constVar,
  auto,
  coerceVar,
  viewVar,
  setVar,
  overVar,
  sequenceVar,
  collectVar,
  previewVar,
  toListOfVar,

  -- ** With Isomorphisms
  isoVar,
  isoVar2,
  isoVar3,
  isoVarN,

  -- ** With 'Op's
  liftOp,
  liftOp1,
  liftOp2,
  liftOp3,

  -- ** Generics
  splitBV,
  joinBV,
  BVGroup,

  -- * 'Op'
  Op (..),

  -- ** Creation
  op0,
  opConst,
  idOp,
  bpOp,

  -- *** Giving gradients directly
  op1,
  op2,
  op3,

  -- *** From Isomorphisms
  opCoerce,
  opTup,
  opIso,
  opIsoN,
  opLens,

  -- *** No gradients
  noGrad1,
  noGrad,

  -- * Utility
  Reifies,
) where

import Data.Bifunctor
import Data.Functor.Identity
import Data.Reflection
import Data.Type.Util
import Data.Vinyl.Core
import Data.Vinyl.TypeLevel
import GHC.Generics as G
import Lens.Micro
import Numeric.Backprop.Class
import Numeric.Backprop.Internal
import Numeric.Backprop.Op
import Unsafe.Coerce

-- | 'ZeroFunc's for every item in a type level list based on their
-- 'Num' instances
--
-- @since 0.2.0.0
zfNums :: RPureConstrained Num as => Rec ZeroFunc as
zfNums :: forall (as :: [*]). RPureConstrained Num as => Rec ZeroFunc as
zfNums = forall {k} (c :: k -> Constraint) (ts :: [k]) (f :: k -> *).
RPureConstrained c ts =>
(forall (a :: k). c a => f a) -> Rec f ts
forall (c :: * -> Constraint) (ts :: [*]) (f :: * -> *).
RPureConstrained c ts =>
(forall a. c a => f a) -> Rec f ts
rpureConstrained @Num ZeroFunc a
forall a. Num a => ZeroFunc a
zfNum

-- | 'zeroFunc' for instances of 'Functor'
--
-- @since 0.2.1.0
zfFunctor :: (Backprop a, Functor f) => ZeroFunc (f a)
zfFunctor :: forall a (f :: * -> *). (Backprop a, Functor f) => ZeroFunc (f a)
zfFunctor = (f a -> f a) -> ZeroFunc (f a)
forall a. (a -> a) -> ZeroFunc a
ZF f a -> f a
forall (f :: * -> *) a. (Functor f, Backprop a) => f a -> f a
zeroFunctor
{-# INLINE zfFunctor #-}

-- | 'ZeroFunc's for every item in a type level list based on their
-- 'Num' instances
--
-- @since 0.2.0.0
afNums :: RPureConstrained Num as => Rec AddFunc as
afNums :: forall (as :: [*]). RPureConstrained Num as => Rec AddFunc as
afNums = forall {k} (c :: k -> Constraint) (ts :: [k]) (f :: k -> *).
RPureConstrained c ts =>
(forall (a :: k). c a => f a) -> Rec f ts
forall (c :: * -> Constraint) (ts :: [*]) (f :: * -> *).
RPureConstrained c ts =>
(forall a. c a => f a) -> Rec f ts
rpureConstrained @Num AddFunc a
forall a. Num a => AddFunc a
afNum

-- | 'ZeroFunc's for every item in a type level list based on their
-- 'Num' instances
--
-- @since 0.2.0.0
ofNums :: RPureConstrained Num as => Rec OneFunc as
ofNums :: forall (as :: [*]). RPureConstrained Num as => Rec OneFunc as
ofNums = forall {k} (c :: k -> Constraint) (ts :: [k]) (f :: k -> *).
RPureConstrained c ts =>
(forall (a :: k). c a => f a) -> Rec f ts
forall (c :: * -> Constraint) (ts :: [*]) (f :: * -> *).
RPureConstrained c ts =>
(forall a. c a => f a) -> Rec f ts
rpureConstrained @Num OneFunc a
forall a. Num a => OneFunc a
ofNum

-- | 'OneFunc' for instances of 'Functor'
--
-- @since 0.2.1.0
ofFunctor :: (Backprop a, Functor f) => OneFunc (f a)
ofFunctor :: forall a (f :: * -> *). (Backprop a, Functor f) => OneFunc (f a)
ofFunctor = (f a -> f a) -> OneFunc (f a)
forall a. (a -> a) -> OneFunc a
OF f a -> f a
forall (f :: * -> *) a. (Functor f, Backprop a) => f a -> f a
oneFunctor
{-# INLINE ofFunctor #-}

-- | Generate an 'ZeroFunc' for every type in a type-level list, if every
-- type has an instance of 'Backprop'.
--
-- @since 0.2.0.0
zeroFuncs :: RPureConstrained Backprop as => Rec ZeroFunc as
zeroFuncs :: forall (as :: [*]). RPureConstrained Backprop as => Rec ZeroFunc as
zeroFuncs = forall {k} (c :: k -> Constraint) (ts :: [k]) (f :: k -> *).
RPureConstrained c ts =>
(forall (a :: k). c a => f a) -> Rec f ts
forall (c :: * -> Constraint) (ts :: [*]) (f :: * -> *).
RPureConstrained c ts =>
(forall a. c a => f a) -> Rec f ts
rpureConstrained @Backprop ZeroFunc a
forall a. Backprop a => ZeroFunc a
zeroFunc

-- | Generate an 'AddFunc' for every type in a type-level list, if every
-- type has an instance of 'Backprop'.
--
-- @since 0.2.0.0
addFuncs :: RPureConstrained Backprop as => Rec AddFunc as
addFuncs :: forall (as :: [*]). RPureConstrained Backprop as => Rec AddFunc as
addFuncs = forall {k} (c :: k -> Constraint) (ts :: [k]) (f :: k -> *).
RPureConstrained c ts =>
(forall (a :: k). c a => f a) -> Rec f ts
forall (c :: * -> Constraint) (ts :: [*]) (f :: * -> *).
RPureConstrained c ts =>
(forall a. c a => f a) -> Rec f ts
rpureConstrained @Backprop AddFunc a
forall a. Backprop a => AddFunc a
addFunc

-- | Generate an 'OneFunc' for every type in a type-level list, if every
-- type has an instance of 'Backprop'.
--
-- @since 0.2.0.0
oneFuncs :: RPureConstrained Backprop as => Rec OneFunc as
oneFuncs :: forall (as :: [*]). RPureConstrained Backprop as => Rec OneFunc as
oneFuncs = forall {k} (c :: k -> Constraint) (ts :: [k]) (f :: k -> *).
RPureConstrained c ts =>
(forall (a :: k). c a => f a) -> Rec f ts
forall (c :: * -> Constraint) (ts :: [*]) (f :: * -> *).
RPureConstrained c ts =>
(forall a. c a => f a) -> Rec f ts
rpureConstrained @Backprop OneFunc a
forall a. Backprop a => OneFunc a
oneFunc

-- | Shorter alias for 'constVar', inspired by the /ad/ library.
--
-- @since 0.2.0.0
auto :: a -> BVar s a
auto :: forall a s. a -> BVar s a
auto = a -> BVar s a
forall a s. a -> BVar s a
constVar
{-# INLINE auto #-}

-- | 'Numeric.Backprop.backpropN', but with explicit 'zero' and 'one'.
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)
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)
backpropN Rec ZeroFunc as
zfs OneFunc b
ob forall s. Reifies s W => Rec (BVar s) as -> BVar s b
f Rec Identity as
xs = case Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, b -> Rec Identity as)
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)
backpropWithN Rec ZeroFunc as
zfs Rec (BVar s) as -> BVar s b
forall s. Reifies s W => Rec (BVar s) as -> BVar s b
f Rec Identity as
xs of
  (b
y, b -> Rec Identity as
g) -> (b
y, b -> Rec Identity as
g (OneFunc b -> b -> b
forall a. OneFunc a -> a -> a
runOF OneFunc b
ob b
y))
{-# INLINE backpropN #-}

-- | 'Numeric.Backprop.backprop', but with explicit 'zero' and 'one'.
backprop ::
  ZeroFunc a ->
  OneFunc b ->
  (forall s. Reifies s W => BVar s a -> BVar s b) ->
  a ->
  (b, a)
backprop :: forall a b.
ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, a)
backprop ZeroFunc a
zfa OneFunc b
ofb forall s. Reifies s W => BVar s a -> BVar s b
f =
  (Rec Identity '[a] -> a) -> (b, Rec Identity '[a]) -> (b, a)
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 (\case Identity a
x :& Rec Identity rs
RNil -> a
x)
    ((b, Rec Identity '[a]) -> (b, a))
-> (a -> (b, Rec Identity '[a])) -> a -> (b, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec ZeroFunc '[a]
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) '[a] -> BVar s b)
-> Rec Identity '[a]
-> (b, Rec Identity '[a])
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)
backpropN (ZeroFunc a
zfa ZeroFunc a -> Rec ZeroFunc '[] -> Rec ZeroFunc '[a]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec ZeroFunc '[]
forall {u} (a :: u -> *). Rec a '[]
RNil) OneFunc b
ofb (BVar s a -> BVar s b
forall s. Reifies s W => BVar s a -> BVar s b
f (BVar s a -> BVar s b)
-> (Rec (BVar s) '[a] -> BVar s a) -> Rec (BVar s) '[a] -> BVar s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\case BVar s r
x :& Rec (BVar s) rs
RNil -> BVar s a
BVar s r
x))
    (Rec Identity '[a] -> (b, Rec Identity '[a]))
-> (a -> Rec Identity '[a]) -> a -> (b, Rec Identity '[a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identity a -> Rec Identity '[] -> Rec Identity '[a]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil)
    (Identity a -> Rec Identity '[a])
-> (a -> Identity a) -> a -> Rec Identity '[a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Identity a
forall a. a -> Identity a
Identity
{-# INLINE backprop #-}

-- | 'Numeric.Backprop.backpropWith', but with explicit 'zero'.
--
-- 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)
backpropWith :: forall a b.
ZeroFunc a
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, b -> a)
backpropWith ZeroFunc a
zfa forall s. Reifies s W => BVar s a -> BVar s b
f =
  ((b -> Rec Identity '[a]) -> b -> a)
-> (b, b -> Rec Identity '[a]) -> (b, b -> a)
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 ((\case Identity a
x :& Rec Identity rs
RNil -> a
x) (Rec Identity '[a] -> a) -> (b -> Rec Identity '[a]) -> b -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.)
    ((b, b -> Rec Identity '[a]) -> (b, b -> a))
-> (a -> (b, b -> Rec Identity '[a])) -> a -> (b, b -> a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec ZeroFunc '[a]
-> (forall s. Reifies s W => Rec (BVar s) '[a] -> BVar s b)
-> Rec Identity '[a]
-> (b, b -> Rec Identity '[a])
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)
backpropWithN (ZeroFunc a
zfa ZeroFunc a -> Rec ZeroFunc '[] -> Rec ZeroFunc '[a]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec ZeroFunc '[]
forall {u} (a :: u -> *). Rec a '[]
RNil) (BVar s a -> BVar s b
forall s. Reifies s W => BVar s a -> BVar s b
f (BVar s a -> BVar s b)
-> (Rec (BVar s) '[a] -> BVar s a) -> Rec (BVar s) '[a] -> BVar s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\case BVar s r
x :& Rec (BVar s) rs
RNil -> BVar s a
BVar s r
x))
    (Rec Identity '[a] -> (b, b -> Rec Identity '[a]))
-> (a -> Rec Identity '[a]) -> a -> (b, b -> Rec Identity '[a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identity a -> Rec Identity '[] -> Rec Identity '[a]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil)
    (Identity a -> Rec Identity '[a])
-> (a -> Identity a) -> a -> Rec Identity '[a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Identity a
forall a. a -> Identity a
Identity
{-# INLINE backpropWith #-}

-- | 'evalBP' but with no arguments.  Useful when everything is just given
-- through 'constVar'.
evalBP0 :: (forall s. Reifies s W => BVar s a) -> a
evalBP0 :: forall a. (forall s. Reifies s W => BVar s a) -> a
evalBP0 forall s. Reifies s W => BVar s a
x = (forall s. Reifies s W => Rec (BVar s) '[] -> BVar s a)
-> Rec Identity '[] -> a
forall (as :: [*]) b.
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as -> b
evalBPN (BVar s a -> Rec (BVar s) '[] -> BVar s a
forall a b. a -> b -> a
const BVar s a
forall s. Reifies s W => BVar s a
x) Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil
{-# INLINE evalBP0 #-}

-- | Turn a function @'BVar' s a -> 'BVar' s b@ into the function @a -> b@
-- that it represents.
--
-- Benchmarks show that this should have virtually no overhead over
-- directly writing a @a -> b@. 'BVar' is, in this situation, a zero-cost
-- abstraction, performance-wise.
--
-- See documentation of 'Numeric.Backprop.backprop' for more information.
evalBP :: (forall s. Reifies s W => BVar s a -> BVar s b) -> a -> b
evalBP :: forall a b.
(forall s. Reifies s W => BVar s a -> BVar s b) -> a -> b
evalBP forall s. Reifies s W => BVar s a -> BVar s b
f = (forall s. Reifies s W => Rec (BVar s) '[a] -> BVar s b)
-> Rec Identity '[a] -> b
forall (as :: [*]) b.
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as -> b
evalBPN (BVar s a -> BVar s b
forall s. Reifies s W => BVar s a -> BVar s b
f (BVar s a -> BVar s b)
-> (Rec (BVar s) '[a] -> BVar s a) -> Rec (BVar s) '[a] -> BVar s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\case BVar s r
x :& Rec (BVar s) rs
RNil -> BVar s a
BVar s r
x)) (Rec Identity '[a] -> b) -> (a -> Rec Identity '[a]) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identity a -> Rec Identity '[] -> Rec Identity '[a]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil) (Identity a -> Rec Identity '[a])
-> (a -> Identity a) -> a -> Rec Identity '[a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Identity a
forall a. a -> Identity a
Identity
{-# INLINE evalBP #-}

-- | 'Numeric.Backprop.gradBP', but with explicit 'zero' and 'one'.
gradBP ::
  ZeroFunc a ->
  OneFunc b ->
  (forall s. Reifies s W => BVar s a -> BVar s b) ->
  a ->
  a
gradBP :: forall a b.
ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> a
gradBP ZeroFunc a
zfa OneFunc b
ofb forall s. Reifies s W => BVar s a -> BVar s b
f = (b, a) -> a
forall a b. (a, b) -> b
snd ((b, a) -> a) -> (a -> (b, a)) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, a)
forall a b.
ZeroFunc a
-> OneFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b)
-> a
-> (b, a)
backprop ZeroFunc a
zfa OneFunc b
ofb BVar s a -> BVar s b
forall s. Reifies s W => BVar s a -> BVar s b
f
{-# INLINE gradBP #-}

-- | 'Numeric.Backprop.gradBP', Nbut with explicit 'zero' and 'one'.
gradBPN ::
  Rec ZeroFunc as ->
  OneFunc b ->
  (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) ->
  Rec Identity as ->
  Rec Identity as
gradBPN :: forall (as :: [*]) b.
Rec ZeroFunc as
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> Rec Identity as
gradBPN Rec ZeroFunc as
zfas OneFunc b
ofb forall s. Reifies s W => Rec (BVar s) as -> BVar s b
f = (b, Rec Identity as) -> Rec Identity as
forall a b. (a, b) -> b
snd ((b, Rec Identity as) -> Rec Identity as)
-> (Rec Identity as -> (b, Rec Identity as))
-> Rec Identity as
-> Rec Identity as
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec ZeroFunc as
-> OneFunc b
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, Rec Identity as)
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)
backpropN Rec ZeroFunc as
zfas OneFunc b
ofb Rec (BVar s) as -> BVar s b
forall s. Reifies s W => Rec (BVar s) as -> BVar s b
f
{-# INLINE gradBPN #-}

-- | 'Numeric.Backprop.backprop2', but with explicit 'zero' and 'one'.
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))
backprop2 :: forall a b c.
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))
backprop2 ZeroFunc a
zfa ZeroFunc b
zfb OneFunc c
ofc forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f a
x b
y =
  (Rec Identity '[a, b] -> (a, b))
-> (c, Rec Identity '[a, b]) -> (c, (a, b))
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 (\(Identity a
dx :& Identity b
dy :& Rec Identity rs
RNil) -> (a
dx, b
dy)) ((c, Rec Identity '[a, b]) -> (c, (a, b)))
-> (c, Rec Identity '[a, b]) -> (c, (a, b))
forall a b. (a -> b) -> a -> b
$
    Rec ZeroFunc '[a, b]
-> OneFunc c
-> (forall s. Reifies s W => Rec (BVar s) '[a, b] -> BVar s c)
-> Rec Identity '[a, b]
-> (c, Rec Identity '[a, b])
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)
backpropN
      (ZeroFunc a
zfa ZeroFunc a -> Rec ZeroFunc '[b] -> Rec ZeroFunc '[a, b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& ZeroFunc b
zfb ZeroFunc b -> Rec ZeroFunc '[] -> Rec ZeroFunc '[b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec ZeroFunc '[]
forall {u} (a :: u -> *). Rec a '[]
RNil)
      OneFunc c
ofc
      (\(BVar s r
x' :& BVar s r
y' :& Rec (BVar s) rs
RNil) -> BVar s a -> BVar s b -> BVar s c
forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f BVar s a
BVar s r
x' BVar s b
BVar s r
y')
      (a -> Identity a
forall a. a -> Identity a
Identity a
x Identity a -> Rec Identity '[b] -> Rec Identity '[a, b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& b -> Identity b
forall a. a -> Identity a
Identity b
y Identity b -> Rec Identity '[] -> Rec Identity '[b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil)
{-# INLINE backprop2 #-}

-- | 'Numeric.Backprop.backpropWith2', but with explicit 'zero'.
--
-- Note that argument order changed in v0.2.4.
--
-- @since 0.2.0.0
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))
backpropWith2 :: forall a b c.
ZeroFunc a
-> ZeroFunc b
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (c, c -> (a, b))
backpropWith2 ZeroFunc a
zfa ZeroFunc b
zfb forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f a
x b
y =
  ((c -> Rec Identity '[a, b]) -> c -> (a, b))
-> (c, c -> Rec Identity '[a, b]) -> (c, c -> (a, b))
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 ((\(Identity a
dx :& Identity b
dy :& Rec Identity rs
RNil) -> (a
dx, b
dy)) (Rec Identity '[a, b] -> (a, b))
-> (c -> Rec Identity '[a, b]) -> c -> (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((c, c -> Rec Identity '[a, b]) -> (c, c -> (a, b)))
-> (c, c -> Rec Identity '[a, b]) -> (c, c -> (a, b))
forall a b. (a -> b) -> a -> b
$
    Rec ZeroFunc '[a, b]
-> (forall s. Reifies s W => Rec (BVar s) '[a, b] -> BVar s c)
-> Rec Identity '[a, b]
-> (c, c -> Rec Identity '[a, b])
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)
backpropWithN
      (ZeroFunc a
zfa ZeroFunc a -> Rec ZeroFunc '[b] -> Rec ZeroFunc '[a, b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& ZeroFunc b
zfb ZeroFunc b -> Rec ZeroFunc '[] -> Rec ZeroFunc '[b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec ZeroFunc '[]
forall {u} (a :: u -> *). Rec a '[]
RNil)
      (\(BVar s r
x' :& BVar s r
y' :& Rec (BVar s) rs
RNil) -> BVar s a -> BVar s b -> BVar s c
forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f BVar s a
BVar s r
x' BVar s b
BVar s r
y')
      (a -> Identity a
forall a. a -> Identity a
Identity a
x Identity a -> Rec Identity '[b] -> Rec Identity '[a, b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& b -> Identity b
forall a. a -> Identity a
Identity b
y Identity b -> Rec Identity '[] -> Rec Identity '[b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil)
{-# INLINE backpropWith2 #-}

-- | 'evalBP' for a two-argument function.  See
-- 'Numeric.Backprop.backprop2' for notes.
evalBP2 ::
  (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c) ->
  a ->
  b ->
  c
evalBP2 :: forall a b c.
(forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a -> b -> c
evalBP2 forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f a
x b
y =
  (forall s. Reifies s W => Rec (BVar s) '[a, b] -> BVar s c)
-> Rec Identity '[a, b] -> c
forall (as :: [*]) b.
(forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as -> b
evalBPN (\(BVar s r
x' :& BVar s r
y' :& Rec (BVar s) rs
RNil) -> BVar s a -> BVar s b -> BVar s c
forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f BVar s a
BVar s r
x' BVar s b
BVar s r
y') (Rec Identity '[a, b] -> c) -> Rec Identity '[a, b] -> c
forall a b. (a -> b) -> a -> b
$
    a -> Identity a
forall a. a -> Identity a
Identity a
x
      Identity a -> Rec Identity '[b] -> Rec Identity '[a, b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& b -> Identity b
forall a. a -> Identity a
Identity b
y
      Identity b -> Rec Identity '[] -> Rec Identity '[b]
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec Identity '[]
forall {u} (a :: u -> *). Rec a '[]
RNil
{-# INLINE evalBP2 #-}

-- | 'Numeric.Backprop.gradBP2' with explicit 'zero' and 'one'.
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)
gradBP2 :: forall a b c.
ZeroFunc a
-> ZeroFunc b
-> OneFunc c
-> (forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c)
-> a
-> b
-> (a, b)
gradBP2 ZeroFunc a
zfa ZeroFunc b
zfb OneFunc c
ofc forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f a
x = (c, (a, b)) -> (a, b)
forall a b. (a, b) -> b
snd ((c, (a, b)) -> (a, b)) -> (b -> (c, (a, b))) -> b -> (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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))
forall a b c.
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))
backprop2 ZeroFunc a
zfa ZeroFunc b
zfb OneFunc c
ofc BVar s a -> BVar s b -> BVar s c
forall s. Reifies s W => BVar s a -> BVar s b -> BVar s c
f a
x
{-# INLINE gradBP2 #-}

-- | 'Numeric.Backprop.bpOp' with explicit 'zero'.
bpOp ::
  Rec ZeroFunc as ->
  (forall s. Reifies s W => Rec (BVar s) as -> BVar s b) ->
  Op as b
bpOp :: forall (as :: [*]) b.
Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Op as b
bpOp Rec ZeroFunc as
zfs forall s. Reifies s W => Rec (BVar s) as -> BVar s b
f = (Rec Identity as -> (b, b -> Rec Identity as)) -> Op as b
forall (as :: [*]) a.
(Rec Identity as -> (a, a -> Rec Identity as)) -> Op as a
Op (Rec ZeroFunc as
-> (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
-> Rec Identity as
-> (b, b -> Rec Identity as)
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)
backpropWithN Rec ZeroFunc as
zfs Rec (BVar s) as -> BVar s b
forall s. Reifies s W => Rec (BVar s) as -> BVar s b
f)
{-# INLINE bpOp #-}

-- | 'Numeric.Backprop.overVar' with explicit 'add' and 'zero'.
--
-- @since 0.2.4.0
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
overVar :: forall s a b.
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
overVar AddFunc a
afa AddFunc b
afb ZeroFunc a
zfa ZeroFunc b
zfb Lens' b a
l BVar s a -> BVar s a
f BVar s b
x = AddFunc a
-> AddFunc b
-> ZeroFunc a
-> Lens' b a
-> BVar s a
-> BVar s b
-> BVar s b
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
setVar AddFunc a
afa AddFunc b
afb ZeroFunc a
zfa (a -> f a) -> b -> f b
Lens' b a
l (BVar s a -> BVar s a
f (AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
forall a b s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
viewVar AddFunc a
afa ZeroFunc b
zfb (a -> f a) -> b -> f b
Lens' b a
l BVar s b
x)) BVar s b
x
{-# INLINE overVar #-}

-- | 'Numeric.Backprop.isoVar' with explicit 'add' and 'zero'.
isoVar ::
  Reifies s W =>
  AddFunc a ->
  (a -> b) ->
  (b -> a) ->
  BVar s a ->
  BVar s b
isoVar :: 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
f b -> a
g = AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1 AddFunc a
af ((a -> b) -> (b -> a) -> Op '[a] b
forall a b. (a -> b) -> (b -> a) -> Op '[a] b
opIso a -> b
f b -> a
g)
{-# INLINE isoVar #-}

-- | 'Numeric.Backprop.isoVar2' with explicit 'add' and 'zero'.
isoVar2 ::
  Reifies s W =>
  AddFunc a ->
  AddFunc b ->
  (a -> b -> c) ->
  (c -> (a, b)) ->
  BVar s a ->
  BVar s b ->
  BVar s c
isoVar2 :: forall s a b c.
Reifies s W =>
AddFunc a
-> AddFunc b
-> (a -> b -> c)
-> (c -> (a, b))
-> BVar s a
-> BVar s b
-> BVar s c
isoVar2 AddFunc a
afa AddFunc b
afb a -> b -> c
f c -> (a, b)
g = AddFunc a
-> AddFunc b -> Op '[a, b] c -> BVar s a -> BVar s b -> BVar s c
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 a
afa AddFunc b
afb ((a -> b -> c) -> (c -> (a, b)) -> Op '[a, b] c
forall a b c. (a -> b -> c) -> (c -> (a, b)) -> Op '[a, b] c
opIso2 a -> b -> c
f c -> (a, b)
g)
{-# INLINE isoVar2 #-}

-- | 'Numeric.Backprop.isoVar3' with explicit 'add' and 'zero'.
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
isoVar3 :: forall s a b c d.
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
isoVar3 AddFunc a
afa AddFunc b
afb AddFunc c
afc a -> b -> c -> d
f d -> (a, b, c)
g = AddFunc a
-> AddFunc b
-> AddFunc c
-> Op '[a, b, c] d
-> BVar s a
-> BVar s b
-> BVar s c
-> BVar s d
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
liftOp3 AddFunc a
afa AddFunc b
afb AddFunc c
afc ((a -> b -> c -> d) -> (d -> (a, b, c)) -> Op '[a, b, c] d
forall a b c d.
(a -> b -> c -> d) -> (d -> (a, b, c)) -> Op '[a, b, c] d
opIso3 a -> b -> c -> d
f d -> (a, b, c)
g)
{-# INLINE isoVar3 #-}

-- | 'Numeric.Backprop.isoVarN' with explicit 'add' and 'zero'.
isoVarN ::
  Reifies s W =>
  Rec AddFunc as ->
  (Rec Identity as -> b) ->
  (b -> Rec Identity as) ->
  Rec (BVar s) as ->
  BVar s b
isoVarN :: forall s (as :: [*]) b.
Reifies s W =>
Rec AddFunc as
-> (Rec Identity as -> b)
-> (b -> Rec Identity as)
-> Rec (BVar s) as
-> BVar s b
isoVarN Rec AddFunc as
afs Rec Identity as -> b
f b -> Rec Identity as
g = Rec AddFunc as -> Op as b -> Rec (BVar s) as -> BVar s b
forall (as :: [*]) b s.
Reifies s W =>
Rec AddFunc as -> Op as b -> Rec (BVar s) as -> BVar s b
liftOp Rec AddFunc as
afs ((Rec Identity as -> b) -> (b -> Rec Identity as) -> Op as b
forall (as :: [*]) b.
(Rec Identity as -> b) -> (b -> Rec Identity as) -> Op as b
opIsoN Rec Identity as -> b
f b -> Rec Identity as
g)
{-# INLINE isoVarN #-}

-- | Helper class for generically "splitting" and "joining" 'BVar's into
-- constructors.  See 'Numeric.Backprop.splitBV' and
-- 'Numeric.Backprop.joinBV'.
--
-- See "Numeric.Backprop#hkd" for a tutorial on how to use this.
--
-- Instances should be available for types made with one constructor whose
-- fields are all instances of 'Backprop', with a 'Generic' instance.
--
-- @since 0.2.2.0
class BVGroup s as i o | o -> i, i -> as where
  -- | Helper method for generically "splitting" 'BVar's out of
  -- constructors inside a 'BVar'.  See 'splitBV'.
  gsplitBV :: Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()

  -- | Helper method for generically "joining" 'BVar's inside
  -- a constructor into a 'BVar'.  See 'joinBV'.
  gjoinBV :: Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())

instance BVGroup s '[] (K1 i a) (K1 i (BVar s a)) where
  gsplitBV :: Rec AddFunc '[]
-> Rec ZeroFunc '[] -> BVar s (K1 i a ()) -> K1 i (BVar s a) ()
gsplitBV Rec AddFunc '[]
_ Rec ZeroFunc '[]
_ = BVar s a -> K1 i (BVar s a) ()
forall k i c (p :: k). c -> K1 i c p
K1 (BVar s a -> K1 i (BVar s a) ())
-> (BVar s (K1 i a ()) -> BVar s a)
-> BVar s (K1 i a ())
-> K1 i (BVar s a) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BVar s (K1 i a ()) -> BVar s a
forall a b s. Coercible a b => BVar s a -> BVar s b
coerceVar
  {-# INLINE gsplitBV #-}
  gjoinBV :: Rec AddFunc '[]
-> Rec ZeroFunc '[] -> K1 i (BVar s a) () -> BVar s (K1 i a ())
gjoinBV Rec AddFunc '[]
_ Rec ZeroFunc '[]
_ = BVar s a -> BVar s (K1 i a ())
forall a b s. Coercible a b => BVar s a -> BVar s b
coerceVar (BVar s a -> BVar s (K1 i a ()))
-> (K1 i (BVar s a) () -> BVar s a)
-> K1 i (BVar s a) ()
-> BVar s (K1 i a ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. K1 i (BVar s a) () -> BVar s a
forall k i c (p :: k). K1 i c p -> c
unK1
  {-# INLINE gjoinBV #-}

instance
  BVGroup s as i o =>
  BVGroup s as (M1 p c i) (M1 p c o)
  where
  gsplitBV :: Rec AddFunc as
-> Rec ZeroFunc as -> BVar s (M1 p c i ()) -> M1 p c o ()
gsplitBV Rec AddFunc as
afs Rec ZeroFunc as
zfs = o () -> M1 p c o ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (o () -> M1 p c o ())
-> (BVar s (M1 p c i ()) -> o ())
-> BVar s (M1 p c i ())
-> M1 p c o ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
gsplitBV Rec AddFunc as
afs Rec ZeroFunc as
zfs (BVar s (i ()) -> o ())
-> (BVar s (M1 p c i ()) -> BVar s (i ()))
-> BVar s (M1 p c i ())
-> o ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b s. Coercible a b => BVar s a -> BVar s b
coerceVar @_ @(i ())
  {-# INLINE gsplitBV #-}
  gjoinBV :: Rec AddFunc as
-> Rec ZeroFunc as -> M1 p c o () -> BVar s (M1 p c i ())
gjoinBV Rec AddFunc as
afs Rec ZeroFunc as
zfs = forall a b s. Coercible a b => BVar s a -> BVar s b
coerceVar @(i ()) (BVar s (i ()) -> BVar s (M1 p c i ()))
-> (M1 p c o () -> BVar s (i ()))
-> M1 p c o ()
-> BVar s (M1 p c i ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
gjoinBV Rec AddFunc as
afs Rec ZeroFunc as
zfs (o () -> BVar s (i ()))
-> (M1 p c o () -> o ()) -> M1 p c o () -> BVar s (i ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M1 p c o () -> o ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1
  {-# INLINE gjoinBV #-}

instance BVGroup s '[] V1 V1 where
  gsplitBV :: Rec AddFunc '[] -> Rec ZeroFunc '[] -> BVar s (V1 ()) -> V1 ()
gsplitBV Rec AddFunc '[]
_ Rec ZeroFunc '[]
_ = BVar s (V1 ()) -> V1 ()
forall a b. a -> b
unsafeCoerce
  {-# INLINE gsplitBV #-}
  gjoinBV :: Rec AddFunc '[] -> Rec ZeroFunc '[] -> V1 () -> BVar s (V1 ())
gjoinBV Rec AddFunc '[]
_ Rec ZeroFunc '[]
_ = \case {}
  {-# INLINE gjoinBV #-}

instance BVGroup s '[] U1 U1 where
  gsplitBV :: Rec AddFunc '[] -> Rec ZeroFunc '[] -> BVar s (U1 ()) -> U1 ()
gsplitBV Rec AddFunc '[]
_ Rec ZeroFunc '[]
_ BVar s (U1 ())
_ = U1 ()
forall k (p :: k). U1 p
U1
  {-# INLINE gsplitBV #-}
  gjoinBV :: Rec AddFunc '[] -> Rec ZeroFunc '[] -> U1 () -> BVar s (U1 ())
gjoinBV Rec AddFunc '[]
_ Rec ZeroFunc '[]
_ U1 ()
_ = U1 () -> BVar s (U1 ())
forall a s. a -> BVar s a
constVar U1 ()
forall k (p :: k). U1 p
U1
  {-# INLINE gjoinBV #-}

instance
  ( Reifies s W
  , BVGroup s as i1 o1
  , BVGroup s bs i2 o2
  , cs ~ (as ++ bs)
  , RecApplicative as
  ) =>
  BVGroup s (i1 () ': i2 () ': cs) (i1 :*: i2) (o1 :*: o2)
  where
  gsplitBV :: Rec AddFunc (i1 () : i2 () : cs)
-> Rec ZeroFunc (i1 () : i2 () : cs)
-> BVar s ((:*:) i1 i2 ())
-> (:*:) o1 o2 ()
gsplitBV (AddFunc r
afa :& AddFunc r
afb :& Rec AddFunc rs
afs) (ZeroFunc r
zfa :& ZeroFunc r
zfb :& Rec ZeroFunc rs
zfs) BVar s ((:*:) i1 i2 ())
xy = o1 ()
x o1 () -> o2 () -> (:*:) o1 o2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: o2 ()
y
    where
      (Rec AddFunc as
afas, Rec AddFunc bs
afbs) = Rec AddFunc (as ++ bs) -> (Rec AddFunc as, Rec AddFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec AddFunc rs
Rec AddFunc (as ++ bs)
afs
      (Rec ZeroFunc as
zfas, Rec ZeroFunc bs
zfbs) = Rec ZeroFunc (as ++ bs) -> (Rec ZeroFunc as, Rec ZeroFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec ZeroFunc rs
Rec ZeroFunc (as ++ bs)
zfs
      zfab :: ZeroFunc ((:*:) i1 i2 ())
zfab = ((:*:) i1 i2 () -> (:*:) i1 i2 ()) -> ZeroFunc ((:*:) i1 i2 ())
forall a. (a -> a) -> ZeroFunc a
ZF (((:*:) i1 i2 () -> (:*:) i1 i2 ()) -> ZeroFunc ((:*:) i1 i2 ()))
-> ((:*:) i1 i2 () -> (:*:) i1 i2 ()) -> ZeroFunc ((:*:) i1 i2 ())
forall a b. (a -> b) -> a -> b
$ \(i1 ()
xx :*: i2 ()
yy) -> ZeroFunc (i1 ()) -> i1 () -> i1 ()
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc r
ZeroFunc (i1 ())
zfa i1 ()
xx i1 () -> i2 () -> (:*:) i1 i2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: ZeroFunc (i2 ()) -> i2 () -> i2 ()
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc r
ZeroFunc (i2 ())
zfb i2 ()
yy
      x :: o1 ()
x = Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i1 ()) -> o1 ()
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
gsplitBV Rec AddFunc as
afas Rec ZeroFunc as
zfas (BVar s (i1 ()) -> o1 ())
-> (BVar s ((:*:) i1 i2 ()) -> BVar s (i1 ()))
-> BVar s ((:*:) i1 i2 ())
-> o1 ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc (i1 ())
-> ZeroFunc ((:*:) i1 i2 ())
-> Lens' ((:*:) i1 i2 ()) (i1 ())
-> BVar s ((:*:) i1 i2 ())
-> BVar s (i1 ())
forall a b s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
viewVar AddFunc r
AddFunc (i1 ())
afa ZeroFunc ((:*:) i1 i2 ())
zfab (i1 () -> f (i1 ())) -> (:*:) i1 i2 () -> f ((:*:) i1 i2 ())
forall {k} (f1 :: k -> *) (g :: k -> *) (a :: k) (f2 :: * -> *).
Functor f2 =>
(f1 a -> f2 (f1 a)) -> (:*:) f1 g a -> f2 ((:*:) f1 g a)
Lens' ((:*:) i1 i2 ()) (i1 ())
p1 (BVar s ((:*:) i1 i2 ()) -> o1 ())
-> BVar s ((:*:) i1 i2 ()) -> o1 ()
forall a b. (a -> b) -> a -> b
$ BVar s ((:*:) i1 i2 ())
xy
      y :: o2 ()
y = Rec AddFunc bs -> Rec ZeroFunc bs -> BVar s (i2 ()) -> o2 ()
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
gsplitBV Rec AddFunc bs
afbs Rec ZeroFunc bs
zfbs (BVar s (i2 ()) -> o2 ())
-> (BVar s ((:*:) i1 i2 ()) -> BVar s (i2 ()))
-> BVar s ((:*:) i1 i2 ())
-> o2 ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc (i2 ())
-> ZeroFunc ((:*:) i1 i2 ())
-> Lens' ((:*:) i1 i2 ()) (i2 ())
-> BVar s ((:*:) i1 i2 ())
-> BVar s (i2 ())
forall a b s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
viewVar AddFunc r
AddFunc (i2 ())
afb ZeroFunc ((:*:) i1 i2 ())
zfab (i2 () -> f (i2 ())) -> (:*:) i1 i2 () -> f ((:*:) i1 i2 ())
forall {k} (f1 :: k -> *) (g :: k -> *) (a :: k) (f2 :: * -> *).
Functor f2 =>
(g a -> f2 (g a)) -> (:*:) f1 g a -> f2 ((:*:) f1 g a)
Lens' ((:*:) i1 i2 ()) (i2 ())
p2 (BVar s ((:*:) i1 i2 ()) -> o2 ())
-> BVar s ((:*:) i1 i2 ()) -> o2 ()
forall a b. (a -> b) -> a -> b
$ BVar s ((:*:) i1 i2 ())
xy
  {-# INLINE gsplitBV #-}
  gjoinBV :: Rec AddFunc (i1 () : i2 () : cs)
-> Rec ZeroFunc (i1 () : i2 () : cs)
-> (:*:) o1 o2 ()
-> BVar s ((:*:) i1 i2 ())
gjoinBV (AddFunc r
afa :& AddFunc r
afb :& Rec AddFunc rs
afs) (ZeroFunc r
_ :& ZeroFunc r
_ :& Rec ZeroFunc rs
zfs) (o1 ()
x :*: o2 ()
y) =
    AddFunc r
-> AddFunc r
-> (r -> r -> (:*:) i1 i2 ())
-> ((:*:) i1 i2 () -> (r, r))
-> BVar s r
-> BVar s r
-> BVar s ((:*:) i1 i2 ())
forall s a b c.
Reifies s W =>
AddFunc a
-> AddFunc b
-> (a -> b -> c)
-> (c -> (a, b))
-> BVar s a
-> BVar s b
-> BVar s c
isoVar2
      AddFunc r
afa
      AddFunc r
afb
      r -> r -> (:*:) i1 i2 ()
i1 () -> i2 () -> (:*:) i1 i2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:)
      (:*:) i1 i2 () -> (r, r)
(:*:) i1 i2 () -> (i1 (), i2 ())
forall {f :: * -> *} {g :: * -> *} {p}. (:*:) f g p -> (f p, g p)
unP
      (Rec AddFunc as -> Rec ZeroFunc as -> o1 () -> BVar s (i1 ())
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
gjoinBV Rec AddFunc as
afas Rec ZeroFunc as
zfas o1 ()
x)
      (Rec AddFunc bs -> Rec ZeroFunc bs -> o2 () -> BVar s (i2 ())
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
gjoinBV Rec AddFunc bs
afbs Rec ZeroFunc bs
zfbs o2 ()
y)
    where
      (Rec AddFunc as
afas, Rec AddFunc bs
afbs) = Rec AddFunc (as ++ bs) -> (Rec AddFunc as, Rec AddFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec AddFunc rs
Rec AddFunc (as ++ bs)
afs
      (Rec ZeroFunc as
zfas, Rec ZeroFunc bs
zfbs) = Rec ZeroFunc (as ++ bs) -> (Rec ZeroFunc as, Rec ZeroFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec ZeroFunc rs
Rec ZeroFunc (as ++ bs)
zfs
      unP :: (:*:) f g p -> (f p, g p)
unP (f p
xx :*: g p
yy) = (f p
xx, g p
yy)
  {-# INLINE gjoinBV #-}

-- | This instance is possible but it is not clear when it would be useful
instance
  ( Reifies s W
  , BVGroup s as i1 o1
  , BVGroup s bs i2 o2
  , cs ~ (as ++ bs)
  , RecApplicative as
  ) =>
  BVGroup s (i1 () ': i2 () ': cs) (i1 :+: i2) (o1 :+: o2)
  where
  gsplitBV :: Rec AddFunc (i1 () : i2 () : cs)
-> Rec ZeroFunc (i1 () : i2 () : cs)
-> BVar s ((:+:) i1 i2 ())
-> (:+:) o1 o2 ()
gsplitBV (AddFunc r
afa :& AddFunc r
afb :& Rec AddFunc rs
afs) (ZeroFunc r
zfa :& ZeroFunc r
zfb :& Rec ZeroFunc rs
zfs) BVar s ((:+:) i1 i2 ())
xy =
    case AddFunc r
-> ZeroFunc ((:+:) i1 i2 ())
-> Traversal' ((:+:) i1 i2 ()) r
-> BVar s ((:+:) i1 i2 ())
-> Maybe (BVar s r)
forall b a s.
Reifies s W =>
AddFunc a
-> ZeroFunc b -> Traversal' b a -> BVar s b -> Maybe (BVar s a)
previewVar AddFunc r
afa ZeroFunc ((:+:) i1 i2 ())
zf (r -> f r) -> (:+:) i1 i2 () -> f ((:+:) i1 i2 ())
(i1 () -> f (i1 ())) -> (:+:) i1 i2 () -> f ((:+:) i1 i2 ())
forall {k} (f1 :: k -> *) (g :: k -> *) (a :: k) (f2 :: * -> *).
Applicative f2 =>
(f1 a -> f2 (f1 a)) -> (:+:) f1 g a -> f2 ((:+:) f1 g a)
Traversal' ((:+:) i1 i2 ()) r
s1 BVar s ((:+:) i1 i2 ())
xy of
      Just BVar s r
x -> o1 () -> (:+:) o1 o2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (o1 () -> (:+:) o1 o2 ()) -> o1 () -> (:+:) o1 o2 ()
forall a b. (a -> b) -> a -> b
$ Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i1 ()) -> o1 ()
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
gsplitBV Rec AddFunc as
afas Rec ZeroFunc as
zfas BVar s r
BVar s (i1 ())
x
      Maybe (BVar s r)
Nothing -> case AddFunc r
-> ZeroFunc ((:+:) i1 i2 ())
-> Traversal' ((:+:) i1 i2 ()) r
-> BVar s ((:+:) i1 i2 ())
-> Maybe (BVar s r)
forall b a s.
Reifies s W =>
AddFunc a
-> ZeroFunc b -> Traversal' b a -> BVar s b -> Maybe (BVar s a)
previewVar AddFunc r
afb ZeroFunc ((:+:) i1 i2 ())
zf (r -> f r) -> (:+:) i1 i2 () -> f ((:+:) i1 i2 ())
(i2 () -> f (i2 ())) -> (:+:) i1 i2 () -> f ((:+:) i1 i2 ())
forall {k} (f1 :: k -> *) (g :: k -> *) (a :: k) (f2 :: * -> *).
Applicative f2 =>
(g a -> f2 (g a)) -> (:+:) f1 g a -> f2 ((:+:) f1 g a)
Traversal' ((:+:) i1 i2 ()) r
s2 BVar s ((:+:) i1 i2 ())
xy of
        Just BVar s r
y -> o2 () -> (:+:) o1 o2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (o2 () -> (:+:) o1 o2 ()) -> o2 () -> (:+:) o1 o2 ()
forall a b. (a -> b) -> a -> b
$ Rec AddFunc bs -> Rec ZeroFunc bs -> BVar s (i2 ()) -> o2 ()
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
gsplitBV Rec AddFunc bs
afbs Rec ZeroFunc bs
zfbs BVar s r
BVar s (i2 ())
y
        Maybe (BVar s r)
Nothing -> [Char] -> (:+:) o1 o2 ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Numeric.Backprop.gsplitBV: Internal error occurred"
    where
      zf :: ZeroFunc ((:+:) i1 i2 ())
zf = ((:+:) i1 i2 () -> (:+:) i1 i2 ()) -> ZeroFunc ((:+:) i1 i2 ())
forall a. (a -> a) -> ZeroFunc a
ZF (((:+:) i1 i2 () -> (:+:) i1 i2 ()) -> ZeroFunc ((:+:) i1 i2 ()))
-> ((:+:) i1 i2 () -> (:+:) i1 i2 ()) -> ZeroFunc ((:+:) i1 i2 ())
forall a b. (a -> b) -> a -> b
$ \case
        L1 i1 ()
xx -> i1 () -> (:+:) i1 i2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (i1 () -> (:+:) i1 i2 ()) -> i1 () -> (:+:) i1 i2 ()
forall a b. (a -> b) -> a -> b
$ ZeroFunc (i1 ()) -> i1 () -> i1 ()
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc r
ZeroFunc (i1 ())
zfa i1 ()
xx
        R1 i2 ()
yy -> i2 () -> (:+:) i1 i2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (i2 () -> (:+:) i1 i2 ()) -> i2 () -> (:+:) i1 i2 ()
forall a b. (a -> b) -> a -> b
$ ZeroFunc (i2 ()) -> i2 () -> i2 ()
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc r
ZeroFunc (i2 ())
zfb i2 ()
yy
      (Rec AddFunc as
afas, Rec AddFunc bs
afbs) = Rec AddFunc (as ++ bs) -> (Rec AddFunc as, Rec AddFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec AddFunc rs
Rec AddFunc (as ++ bs)
afs
      (Rec ZeroFunc as
zfas, Rec ZeroFunc bs
zfbs) = Rec ZeroFunc (as ++ bs) -> (Rec ZeroFunc as, Rec ZeroFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec ZeroFunc rs
Rec ZeroFunc (as ++ bs)
zfs
  {-# INLINE gsplitBV #-}
  gjoinBV :: Rec AddFunc (i1 () : i2 () : cs)
-> Rec ZeroFunc (i1 () : i2 () : cs)
-> (:+:) o1 o2 ()
-> BVar s ((:+:) i1 i2 ())
gjoinBV (AddFunc r
afa :& AddFunc r
afb :& Rec AddFunc rs
afs) (ZeroFunc r
zfa :& ZeroFunc r
zfb :& Rec ZeroFunc rs
zfs) = \case
    L1 o1 ()
x ->
      AddFunc r
-> Op '[r] ((:+:) i1 i2 ()) -> BVar s r -> BVar s ((:+:) i1 i2 ())
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1
        AddFunc r
afa
        ((r -> ((:+:) i1 i2 (), (:+:) i1 i2 () -> r))
-> Op '[r] ((:+:) i1 i2 ())
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 (\r
xx -> (i1 () -> (:+:) i1 i2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 r
i1 ()
xx, \case L1 i1 ()
d -> r
i1 ()
d; R1 i2 ()
_ -> ZeroFunc r -> r -> r
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc r
ZeroFunc r
zfa r
xx)))
        (Rec AddFunc as -> Rec ZeroFunc as -> o1 () -> BVar s (i1 ())
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
gjoinBV Rec AddFunc as
afas Rec ZeroFunc as
zfas o1 ()
x)
    R1 o2 ()
y ->
      AddFunc r
-> Op '[r] ((:+:) i1 i2 ()) -> BVar s r -> BVar s ((:+:) i1 i2 ())
forall a b s.
Reifies s W =>
AddFunc a -> Op '[a] b -> BVar s a -> BVar s b
liftOp1
        AddFunc r
afb
        ((r -> ((:+:) i1 i2 (), (:+:) i1 i2 () -> r))
-> Op '[r] ((:+:) i1 i2 ())
forall a b. (a -> (b, b -> a)) -> Op '[a] b
op1 (\r
yy -> (i2 () -> (:+:) i1 i2 ()
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 r
i2 ()
yy, \case L1 i1 ()
_ -> ZeroFunc r -> r -> r
forall a. ZeroFunc a -> a -> a
runZF ZeroFunc r
ZeroFunc r
zfb r
yy; R1 i2 ()
d -> r
i2 ()
d)))
        (Rec AddFunc bs -> Rec ZeroFunc bs -> o2 () -> BVar s (i2 ())
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
gjoinBV Rec AddFunc bs
afbs Rec ZeroFunc bs
zfbs o2 ()
y)
    where
      (Rec AddFunc as
afas, Rec AddFunc bs
afbs) = Rec AddFunc (as ++ bs) -> (Rec AddFunc as, Rec AddFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec AddFunc rs
Rec AddFunc (as ++ bs)
afs
      (Rec ZeroFunc as
zfas, Rec ZeroFunc bs
zfbs) = Rec ZeroFunc (as ++ bs) -> (Rec ZeroFunc as, Rec ZeroFunc bs)
forall {u} (f :: u -> *) (as :: [u]) (bs :: [u]).
RecApplicative as =>
Rec f (as ++ bs) -> (Rec f as, Rec f bs)
splitRec Rec ZeroFunc rs
Rec ZeroFunc (as ++ bs)
zfs
  {-# INLINE gjoinBV #-}

-- | 'Numeric.Backprop.splitBV' with explicit 'add' and 'zero'.
--
-- @since 0.2.2.0
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' of value
  BVar s (z f) ->
  -- | 'BVar's of fields
  z (BVar s)
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)
splitBV AddFunc (Rep (z f) ())
af Rec AddFunc as
afs ZeroFunc (z f)
zf Rec ZeroFunc as
zfs =
  Rep (z (BVar s)) () -> z (BVar s)
forall a x. Generic a => Rep a x -> a
forall x. Rep (z (BVar s)) x -> z (BVar s)
G.to
    (Rep (z (BVar s)) () -> z (BVar s))
-> (BVar s (z f) -> Rep (z (BVar s)) ())
-> BVar s (z f)
-> z (BVar s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec AddFunc as
-> Rec ZeroFunc as -> BVar s (Rep (z f) ()) -> Rep (z (BVar s)) ()
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> BVar s (i ()) -> o ()
gsplitBV Rec AddFunc as
afs Rec ZeroFunc as
zfs
    (BVar s (Rep (z f) ()) -> Rep (z (BVar s)) ())
-> (BVar s (z f) -> BVar s (Rep (z f) ()))
-> BVar s (z f)
-> Rep (z (BVar s)) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddFunc (Rep (z f) ())
-> ZeroFunc (z f)
-> Lens' (z f) (Rep (z f) ())
-> BVar s (z f)
-> BVar s (Rep (z f) ())
forall a b s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
viewVar AddFunc (Rep (z f) ())
af ZeroFunc (z f)
zf ((z f -> Rep (z f) ())
-> (z f -> Rep (z f) () -> z f) -> Lens' (z f) (Rep (z f) ())
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (forall a x. Generic a => a -> Rep a x
from @(z f) @()) ((Rep (z f) () -> z f) -> z f -> Rep (z f) () -> z f
forall a b. a -> b -> a
const Rep (z f) () -> z f
forall a x. Generic a => Rep a x -> a
forall x. Rep (z f) x -> z f
G.to))
{-# INLINE splitBV #-}

-- | 'Numeric.Backprop.joinBV' with explicit 'add' and 'zero'.
--
-- @since 0.2.2.0
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 ->
  -- | 'BVar's of fields
  z (BVar s) ->
  -- | 'BVar' of combined value
  BVar s (z f)
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)
joinBV AddFunc (z f)
af Rec AddFunc as
afs ZeroFunc (Rep (z f) ())
zf Rec ZeroFunc as
zfs =
  AddFunc (z f)
-> ZeroFunc (Rep (z f) ())
-> Lens' (Rep (z f) ()) (z f)
-> BVar s (Rep (z f) ())
-> BVar s (z f)
forall a b s.
Reifies s W =>
AddFunc a -> ZeroFunc b -> Lens' b a -> BVar s b -> BVar s a
viewVar AddFunc (z f)
af ZeroFunc (Rep (z f) ())
zf ((Rep (z f) () -> z f)
-> (Rep (z f) () -> z f -> Rep (z f) ())
-> Lens' (Rep (z f) ()) (z f)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Rep (z f) () -> z f
forall a x. Generic a => Rep a x -> a
forall x. Rep (z f) x -> z f
G.to ((z f -> Rep (z f) ()) -> Rep (z f) () -> z f -> Rep (z f) ()
forall a b. a -> b -> a
const z f -> Rep (z f) ()
forall x. z f -> Rep (z f) x
forall a x. Generic a => a -> Rep a x
from))
    (BVar s (Rep (z f) ()) -> BVar s (z f))
-> (z (BVar s) -> BVar s (Rep (z f) ()))
-> z (BVar s)
-> BVar s (z f)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rec AddFunc as
-> Rec ZeroFunc as -> Rep (z (BVar s)) () -> BVar s (Rep (z f) ())
forall s (as :: [*]) (i :: * -> *) (o :: * -> *).
BVGroup s as i o =>
Rec AddFunc as -> Rec ZeroFunc as -> o () -> BVar s (i ())
gjoinBV Rec AddFunc as
afs Rec ZeroFunc as
zfs
    (Rep (z (BVar s)) () -> BVar s (Rep (z f) ()))
-> (z (BVar s) -> Rep (z (BVar s)) ())
-> z (BVar s)
-> BVar s (Rep (z f) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a x. Generic a => a -> Rep a x
from @(z (BVar s)) @()
{-# INLINE joinBV #-}