module DDF.Diff where
import DDF.DLang
import qualified Data.Map as M
import qualified DDF.Map as Map
instance DBI r => DBI (Diff r v) where
z = Diff z
s (Diff x) = Diff $ s x
abs (Diff f) = Diff $ abs f
app (Diff f) (Diff x) = Diff $ app f x
hoas f = Diff $ hoas (\x -> runDiff $ f $ Diff x)
liftEnv (Diff x) = Diff $ liftEnv x
instance Bool r => Bool (Diff r v) where
bool x = Diff $ bool x
ite = Diff ite
instance Char r => Char (Diff r v) where
char = Diff . char
instance Prod r => Prod (Diff r v) where
mkProd = Diff mkProd
zro = Diff zro
fst = Diff fst
instance Dual r => Dual (Diff r v) where
dual = Diff $ dual
runDual = Diff $ runDual
instance (Vector r v, Double r, Dual r) => Double (Diff r v) where
double x = Diff $ mkDual2 (double x) zero
doublePlus = Diff $ lam2 $ \l r ->
mkDual2 (plus2 (dualOrig1 l) (dualOrig1 r)) (plus2 (dualDiff1 l) (dualDiff1 r))
doubleMinus = Diff $ lam2 $ \l r ->
mkDual2 (minus2 (dualOrig1 l) (dualOrig1 r)) (minus2 (dualDiff1 l) (dualDiff1 r))
doubleMult = Diff $ lam2 $ \l r ->
mkDual2 (mult2 (dualOrig1 l) (dualOrig1 r))
(plus2 (mult2 (dualOrig1 l) (dualDiff1 r)) (mult2 (dualOrig1 r) (dualDiff1 l)))
doubleDivide = Diff $ lam2 $ \l r ->
mkDual2 (divide2 (dualOrig1 l) (dualOrig1 r))
(divide2 (minus2 (mult2 (dualOrig1 r) (dualDiff1 l)) (mult2 (dualOrig1 l) (dualDiff1 r)))
(mult2 (dualOrig1 r) (dualOrig1 r)))
doubleExp = Diff $ lam $ \x -> let_2 (doubleExp1 (dualOrig1 x)) (lam $ \e -> mkDual2 e (mult2 e (dualDiff1 x)))
instance (Vector r v, Lang r) => Float (Diff r v) where
float x = Diff $ mkDual2 (float x) zero
floatPlus = Diff $ lam2 $ \l r ->
mkDual2 (plus2 (dualOrig1 l) (dualOrig1 r)) (plus2 (dualDiff1 l) (dualDiff1 r))
floatMinus = Diff $ lam2 $ \l r ->
mkDual2 (minus2 (dualOrig1 l) (dualOrig1 r)) (minus2 (dualDiff1 l) (dualDiff1 r))
floatMult = Diff $ lam2 $ \l r ->
mkDual2 (mult2 (float2Double1 (dualOrig1 l)) (dualOrig1 r))
(plus2 (mult2 (float2Double1 (dualOrig1 l)) (dualDiff1 r)) (mult2 (float2Double1 (dualOrig1 r)) (dualDiff1 l)))
floatDivide = Diff $ lam2 $ \l r ->
mkDual2 (divide2 (dualOrig1 l) (float2Double1 (dualOrig1 r)))
(divide2 (minus2 (mult2 (float2Double1 (dualOrig1 r)) (dualDiff1 l)) (mult2 (float2Double1 (dualOrig1 l)) (dualDiff1 r)))
(float2Double1 (mult2 (float2Double1 (dualOrig1 r)) (dualOrig1 r))))
floatExp = Diff (lam $ \x -> let_2 (floatExp1 (dualOrig1 x)) (lam $ \e -> mkDual2 e (mult2 (float2Double1 e) (dualDiff1 x))))
instance Option r => Option (Diff r v) where
nothing = Diff nothing
just = Diff just
optionMatch = Diff optionMatch
instance Map.Map r => Map.Map (Diff r v) where
empty = Diff Map.empty
singleton = Diff Map.singleton
lookup :: forall h k a. Map.Ord k => Diff r v h (k -> M.Map k a -> Maybe a)
lookup = withDict (Map.diffOrd (Proxy :: Proxy (v, k))) (Diff Map.lookup)
alter :: forall h k a. Map.Ord k => Diff r v h ((Maybe a -> Maybe a) -> k -> M.Map k a -> M.Map k a)
alter = withDict (Map.diffOrd (Proxy :: Proxy (v, k))) (Diff Map.alter)
mapMap = Diff Map.mapMap
instance Bimap r => Bimap (Diff r v) where
instance Unit r => Unit (Diff r v) where
unit = Diff unit
instance (Vector r v, Lang r) => Lang (Diff r v) where
fix = Diff fix
left = Diff left
right = Diff right
sumMatch = Diff sumMatch
exfalso = Diff exfalso
ioRet = Diff ioRet
ioBind = Diff ioBind
nil = Diff nil
cons = Diff cons
listMatch = Diff listMatch
ioMap = Diff ioMap
writer = Diff writer
runWriter = Diff runWriter
float2Double = Diff $ bimap2 float2Double id
double2Float = Diff $ bimap2 double2Float id
state = Diff state
runState = Diff runState
putStrLn = Diff putStrLn
instance (Vector r v, DLang r) => DLang (Diff r v) where