{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Downhill.Linear.Prelude
  ( pattern T2,
    pattern T3,
  )
where

import Downhill.Linear.BackGrad (BackGrad)
import Downhill.Linear.Expr (BasicVector (VecBuilder), maybeToMonoid)
import qualified Downhill.Linear.Lift as Lift
import Prelude (Maybe (Just), Monoid (mempty), fmap, (.))
import qualified Prelude

splitPair :: forall r a b. (BasicVector a, BasicVector b) => BackGrad r (a, b) -> (BackGrad r a, BackGrad r b)
splitPair :: forall r a b.
(BasicVector a, BasicVector b) =>
BackGrad r (a, b) -> (BackGrad r a, BackGrad r b)
splitPair BackGrad r (a, b)
x = (BackGrad r a
bg1, BackGrad r b
bg2)
  where
    go1 :: VecBuilder a -> VecBuilder (a, b)
    go2 :: VecBuilder b -> VecBuilder (a, b)
    go1 :: VecBuilder a -> VecBuilder (a, b)
go1 VecBuilder a
da = forall a. a -> Maybe a
Just (VecBuilder a
da, forall a. Monoid a => a
mempty)
    go2 :: VecBuilder b -> VecBuilder (a, b)
go2 VecBuilder b
db = forall a. a -> Maybe a
Just (forall a. Monoid a => a
mempty, VecBuilder b
db)
    bg1 :: BackGrad r a
    bg2 :: BackGrad r b
    bg1 :: BackGrad r a
bg1 = forall r a z.
BasicVector z =>
(VecBuilder z -> VecBuilder a) -> BackGrad r a -> BackGrad r z
Lift.lift1_sparse VecBuilder a -> VecBuilder (a, b)
go1 BackGrad r (a, b)
x
    bg2 :: BackGrad r b
bg2 = forall r a z.
BasicVector z =>
(VecBuilder z -> VecBuilder a) -> BackGrad r a -> BackGrad r z
Lift.lift1_sparse VecBuilder b -> VecBuilder (a, b)
go2 BackGrad r (a, b)
x

toTriple ::
  forall r a b c.
  (BasicVector a, BasicVector b, BasicVector c) =>
  BackGrad r (a, b, c) ->
  (BackGrad r a, BackGrad r b, BackGrad r c)
toTriple :: forall r a b c.
(BasicVector a, BasicVector b, BasicVector c) =>
BackGrad r (a, b, c) -> (BackGrad r a, BackGrad r b, BackGrad r c)
toTriple BackGrad r (a, b, c)
x = (BackGrad r a
bg1, BackGrad r b
bg2, BackGrad r c
bg3)
  where
    go1 :: VecBuilder a -> VecBuilder (a, b, c)
    go2 :: VecBuilder b -> VecBuilder (a, b, c)
    go3 :: VecBuilder c -> VecBuilder (a, b, c)
    go1 :: VecBuilder a -> VecBuilder (a, b, c)
go1 VecBuilder a
da = forall a. a -> Maybe a
Just (VecBuilder a
da, forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
    go2 :: VecBuilder b -> VecBuilder (a, b, c)
go2 VecBuilder b
db = forall a. a -> Maybe a
Just (forall a. Monoid a => a
mempty, VecBuilder b
db, forall a. Monoid a => a
mempty)
    go3 :: VecBuilder c -> VecBuilder (a, b, c)
go3 VecBuilder c
dc = forall a. a -> Maybe a
Just (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty, VecBuilder c
dc)
    bg1 :: BackGrad r a
    bg2 :: BackGrad r b
    bg3 :: BackGrad r c
    bg1 :: BackGrad r a
bg1 = forall r a z.
BasicVector z =>
(VecBuilder z -> VecBuilder a) -> BackGrad r a -> BackGrad r z
Lift.lift1_sparse VecBuilder a -> VecBuilder (a, b, c)
go1 BackGrad r (a, b, c)
x
    bg2 :: BackGrad r b
bg2 = forall r a z.
BasicVector z =>
(VecBuilder z -> VecBuilder a) -> BackGrad r a -> BackGrad r z
Lift.lift1_sparse VecBuilder b -> VecBuilder (a, b, c)
go2 BackGrad r (a, b, c)
x
    bg3 :: BackGrad r c
bg3 = forall r a z.
BasicVector z =>
(VecBuilder z -> VecBuilder a) -> BackGrad r a -> BackGrad r z
Lift.lift1_sparse VecBuilder c -> VecBuilder (a, b, c)
go3 BackGrad r (a, b, c)
x

-- |
--
-- @
-- getFst :: (BasicVector (DualOf a), BasicVector (DualOf b)) => BackGrad r (a, b) -> BackGrad r a
-- getFst (T2 x _) = x
-- @
--
-- @
-- mkPair :: (BasicVector (DualOf a), BasicVector (DualOf b)) => BackGrad r a -> BackGrad r b -> BackGrad r (a, b)
-- mkPair x y = (T2 x y)
-- @
{-# COMPLETE T2 #-}

pattern T2 :: forall r a b. (BasicVector a, BasicVector b) => BackGrad r a -> BackGrad r b -> BackGrad r (a, b)
pattern $bT2 :: forall r a b.
(BasicVector a, BasicVector b) =>
BackGrad r a -> BackGrad r b -> BackGrad r (a, b)
$mT2 :: forall {r} {r} {a} {b}.
(BasicVector a, BasicVector b) =>
BackGrad r (a, b)
-> (BackGrad r a -> BackGrad r b -> r) -> ((# #) -> r) -> r
T2 a b <-
  (splitPair -> (a, b))
  where
    T2 BackGrad r a
a BackGrad r b
b = forall r a b z.
BasicVector z =>
(VecBuilder z -> VecBuilder a)
-> (VecBuilder z -> VecBuilder b)
-> BackGrad r a
-> BackGrad r b
-> BackGrad r z
Lift.lift2_sparse VecBuilder (a, b) -> VecBuilder a
go1 VecBuilder (a, b) -> VecBuilder b
go2 BackGrad r a
a BackGrad r b
b
      where
        go1 :: VecBuilder (a, b) -> VecBuilder a
        go2 :: VecBuilder (a, b) -> VecBuilder b
        go1 :: VecBuilder (a, b) -> VecBuilder a
go1 = forall m. Monoid m => Maybe m -> m
maybeToMonoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
Prelude.fst
        go2 :: VecBuilder (a, b) -> VecBuilder b
go2 = forall m. Monoid m => Maybe m -> m
maybeToMonoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
Prelude.snd

{-# COMPLETE T3 #-}

pattern T3 ::
  forall r a b c.
  (BasicVector a, BasicVector b, BasicVector c) =>
  BackGrad r a ->
  BackGrad r b ->
  BackGrad r c ->
  BackGrad r (a, b, c)
pattern $bT3 :: forall r a b c.
(BasicVector a, BasicVector b, BasicVector c) =>
BackGrad r a
-> BackGrad r b -> BackGrad r c -> BackGrad r (a, b, c)
$mT3 :: forall {r} {r} {a} {b} {c}.
(BasicVector a, BasicVector b, BasicVector c) =>
BackGrad r (a, b, c)
-> (BackGrad r a -> BackGrad r b -> BackGrad r c -> r)
-> ((# #) -> r)
-> r
T3 a b c <-
  (toTriple -> (a, b, c))
  where
    T3 BackGrad r a
a BackGrad r b
b BackGrad r c
c = forall r a b c z.
BasicVector z =>
(VecBuilder z -> VecBuilder a)
-> (VecBuilder z -> VecBuilder b)
-> (VecBuilder z -> VecBuilder c)
-> BackGrad r a
-> BackGrad r b
-> BackGrad r c
-> BackGrad r z
Lift.lift3_sparse VecBuilder (a, b, c) -> VecBuilder a
go1 VecBuilder (a, b, c) -> VecBuilder b
go2 VecBuilder (a, b, c) -> VecBuilder c
go3 BackGrad r a
a BackGrad r b
b BackGrad r c
c
      where
        go1 :: VecBuilder (a, b, c) -> VecBuilder a
        go2 :: VecBuilder (a, b, c) -> VecBuilder b
        go3 :: VecBuilder (a, b, c) -> VecBuilder c
        go1 :: VecBuilder (a, b, c) -> VecBuilder a
go1 = forall m. Monoid m => Maybe m -> m
maybeToMonoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(VecBuilder a
x, VecBuilder b
_, VecBuilder c
_) -> VecBuilder a
x)
        go2 :: VecBuilder (a, b, c) -> VecBuilder b
go2 = forall m. Monoid m => Maybe m -> m
maybeToMonoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(VecBuilder a
_, VecBuilder b
x, VecBuilder c
_) -> VecBuilder b
x)
        go3 :: VecBuilder (a, b, c) -> VecBuilder c
go3 = forall m. Monoid m => Maybe m -> m
maybeToMonoid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(VecBuilder a
_, VecBuilder b
_, VecBuilder c
x) -> VecBuilder c
x)