module DDF.Lang (module DDF.Lang, module DDF.Bool, module DDF.Char, module DDF.Double, module DDF.Float, module DDF.Bimap, module DDF.Dual) where
import DDF.Bool
import DDF.Char
import DDF.Double
import DDF.Float
import DDF.Bimap
import DDF.Dual
import qualified DDF.Meta.Dual as M
import qualified Control.Monad.Writer as M (Writer)
import qualified GHC.Float as M
import qualified Prelude as M
import qualified Data.Map as M
import qualified DDF.Map as Map
class (Bool r, Char r, Double r, Float r, Bimap r, Dual r) => Lang r where
fix :: r h ((a -> a) -> a)
left :: r h (a -> M.Either a b)
right :: r h (b -> M.Either a b)
sumMatch :: r h ((a -> c) -> (b -> c) -> M.Either a b -> c)
unit :: r h ()
exfalso :: r h (Void -> a)
ioRet :: r h (a -> M.IO a)
ioBind :: r h (M.IO a -> (a -> M.IO b) -> M.IO b)
ioMap :: r h ((a -> b) -> M.IO a -> M.IO b)
nil :: r h [a]
cons :: r h (a -> [a] -> [a])
listMatch :: r h (b -> (a -> [a] -> b) -> [a] -> b)
listAppend :: r h ([a] -> [a] -> [a])
listAppend = lam2 $ \l r -> fix2 (lam $ \self -> listMatch2 r (lam2 $ \a as -> cons2 a (app self as))) l
writer :: r h ((a, w) -> M.Writer w a)
runWriter :: r h (M.Writer w a -> (a, w))
float2Double :: r h (M.Float -> M.Double)
double2Float :: r h (M.Double -> M.Float)
undefined :: r h a
undefined = fix1 id
state :: r h ((x -> (y, x)) -> State x y)
runState :: r h (State x y -> (x -> (y, x)))
putStrLn :: r h (String -> IO ())
class Reify r x where
reify :: x -> r h x
instance Lang r => Reify r () where
reify _ = unit
instance Lang r => Reify r M.Double where
reify = double
instance (Lang repr, Reify repr l, Reify repr r) => Reify repr (l, r) where
reify (l, r) = mkProd2 (reify l) (reify r)
instance Lang repr => ProdCon (Monoid repr) l r where prodCon = Sub Dict
instance Lang repr => ProdCon (Reify repr) l r where prodCon = Sub Dict
instance Lang repr => ProdCon (Vector repr) l r where prodCon = Sub Dict
class Monoid r g => Group r g where
invert :: r h (g -> g)
minus :: r h (g -> g -> g)
default invert :: DBI r => r h (g -> g)
invert = minus1 zero
default minus :: DBI r => r h (g -> g -> g)
minus = lam2 $ \x y -> plus2 x (invert1 y)
class Group r v => Vector r v where
mult :: r h (M.Double -> v -> v)
divide :: r h (v -> M.Double -> v)
default mult :: Double r => r h (M.Double -> v -> v)
mult = lam2 $ \x y -> divide2 y (recip1 x)
default divide :: Double r => r h (v -> M.Double -> v)
divide = lam2 $ \x y -> mult2 (recip1 y) x
instance Lang r => Monoid r () where
zero = unit
plus = const1 $ const1 unit
instance Lang r => Group r () where
invert = const1 unit
minus = const1 $ const1 unit
instance Lang r => Vector r () where
mult = const1 $ const1 unit
divide = const1 $ const1 unit
instance Double r => Monoid r M.Double where
zero = doubleZero
plus = doublePlus
instance Double r => Group r M.Double where
minus = doubleMinus
instance Double r => Vector r M.Double where
mult = doubleMult
divide = doubleDivide
instance Float r => Monoid r M.Float where
zero = floatZero
plus = floatPlus
instance Float r => Group r M.Float where
minus = floatMinus
instance Lang r => Vector r M.Float where
mult = com2 floatMult double2Float
divide = com2 (flip2 com double2Float) floatDivide
instance (Prod repr, Monoid repr l, Monoid repr r) => Monoid repr (l, r) where
zero = mkProd2 zero zero
plus = lam2 $ \l r -> mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))
instance (Prod repr, Group repr l, Group repr r) => Group repr (l, r) where
invert = bimap2 invert invert
instance (Prod repr, Double repr, Vector repr l, Vector repr r) => Vector repr (l, r) where
mult = lam $ \x -> bimap2 (mult1 x) (mult1 x)
instance (Double r, Monoid r v) => Monoid r (M.Double -> v) where
zero = const1 zero
plus = lam3 $ \l r x -> plus2 (app l x) (app r x)
instance (Lang r, Group r v) => Group r (M.Double -> v) where
invert = lam2 $ \l x -> app l (invert1 x)
instance (Lang r, Vector r v) => Vector r (M.Double -> v) where
mult = lam3 $ \l r x -> app r (mult2 l x)
instance Lang r => Monoid r [a] where
zero = nil
plus = listAppend
instance Lang r => Functor r [] where
map = lam $ \f -> fix1 $ lam $ \self -> listMatch2 nil (lam2 $ \x xs -> cons2 (app f x) $ app self xs)
instance Lang r => BiFunctor r Either where
bimap = lam2 $ \l r -> sumMatch2 (com2 left l) (com2 right r)
instance Prod r => BiFunctor r (,) where
bimap = lam3 $ \l r p -> mkProd2 (app l (zro1 p)) (app r (fst1 p))
instance Dual r => BiFunctor r M.Dual where
bimap = lam2 $ \l r -> dual `com2` bimap2 l r `com2` runDual
instance Lang r => Functor r (Writer w) where
map = lam $ \f -> com2 writer (com2 (bimap2 f id) runWriter)
instance Lang r => Functor r (M.Map k) where
map = Map.mapMap
instance (Lang r, Monoid r w) => Applicative r (Writer w) where
pure = com2 writer (flip2 mkProd zero)
ap = lam2 $ \f x -> writer1 (mkProd2 (app (zro1 (runWriter1 f)) (zro1 (runWriter1 x))) (plus2 (fst1 (runWriter1 f)) (fst1 (runWriter1 x))))
instance (Lang r, Monoid r w) => Monad r (Writer w) where
join = lam $ \x -> writer1 $ mkProd2 (zro1 $ runWriter1 $ zro1 $ runWriter1 x) (plus2 (fst1 $ runWriter1 $ zro1 $ runWriter1 x) (fst1 $ runWriter1 x))
instance Lang r => Functor r (State l) where
map = lam2 $ \f st -> state1 (com2 (bimap2 f id) (runState1 st))
instance Lang r => Applicative r (State l) where
pure = lam $ \x -> state1 (mkProd1 x)
ap = lam2 $ \f x -> state1 $ lam $ \st -> let_2 (runState2 f st) (lam $ \p -> bimap3 (zro1 p) id (runState2 x (fst1 p)))
instance Lang r => Monad r (State l) where
join = lam $ \x -> state1 $ lam $ \st -> let_2 (runState2 x st) (uncurry1 runState)
instance Lang r => Functor r M.IO where
map = ioMap
instance Lang r => Applicative r M.IO where
pure = ioRet
ap = lam2 $ \f x -> ioBind2 f (flip2 ioMap x)
instance Lang r => Monad r M.IO where
bind = ioBind
instance Lang r => Functor r M.Maybe where
map = lam $ \func -> optionMatch2 nothing (com2 just func)
instance Lang r => Applicative r M.Maybe where
pure = just
ap = optionMatch2 (const1 nothing) map
instance Lang r => Monad r M.Maybe where
bind = lam2 $ \x func -> optionMatch3 nothing func x
cons2 = app2 cons
listMatch2 = app2 listMatch
fix1 = app fix
fix2 = app2 fix
uncurry1 = app uncurry
optionMatch2 = app2 optionMatch
optionMatch3 = app3 optionMatch
mult1 = app mult
mult2 = app2 mult
divide2 = app2 divide
invert1 = app invert
minus1 = app minus
divide1 = app divide
recip = divide1 doubleOne
recip1 = app recip
writer1 = app writer
runWriter1 = app runWriter
ioBind2 = app2 ioBind
minus2 = app2 minus
float2Double1 = app float2Double
doubleExp1 = app doubleExp
floatExp1 = app floatExp
sumMatch2 = app2 sumMatch
state1 = app state
runState1 = app runState
runState2 = app2 runState