{-# LANGUAGE NoImplicitPrelude, MultiParamTypeClasses, FlexibleInstances, NoMonomorphismRestriction #-} module DDF.WithDiff where import DDF.Lang import qualified Prelude as M import DDF.Diff () class Monoid r w => WithDiff r w where withDiff :: r h ((w -> x) -> w -> DiffType x w) withDiff1 = app withDiff selfWithDiff :: (DBI r, WithDiff r w) => r h (w -> DiffType w w) selfWithDiff = withDiff1 id instance Lang r => WithDiff r () where withDiff = const1 id instance Lang r => WithDiff r M.Double where withDiff = lam2 $ \con d -> dual1 $ mkProd2 d (app con doubleOne) instance Lang r => WithDiff r M.Float where withDiff = lam2 $ \con d -> dual1 $ mkProd2 d (app con floatOne) instance (Lang repr, WithDiff repr l, WithDiff repr r) => WithDiff repr (l, r) where withDiff = lam $ \con -> bimap2 (withDiff1 (lam $ \l -> app con (mkProd2 l zero))) (withDiff1 (lam $ \r -> app con (mkProd2 zero r)))