DeepDarkFantasy 0.2017.3.30 → 0.2017.4.1
raw patch · 20 files changed
+1265/−1083 lines, 20 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- DBI: App :: String -> AST -> [AST] -> AST
- DBI: Combine :: (l h x) -> (r h x) -> Combine l r h x
- DBI: Eval :: (h -> x) -> Eval h x
- DBI: ImpW :: (repr h (w -> x)) -> ImpW repr h x
- DBI: Lam :: String -> [String] -> AST -> AST
- DBI: Leaf :: String -> AST
- DBI: NoImpW :: (repr h x) -> ImpW repr h x
- DBI: RunImpW :: (repr h (w -> x)) -> RunImpW repr h x
- DBI: Show :: ([String] -> Int -> AST) -> Show h a
- DBI: WDiff :: repr (Diff v h) (Diff v x) -> WDiff repr v h x
- DBI: [runEval] :: Eval h x -> h -> x
- DBI: [runShow] :: Show h a -> [String] -> Int -> AST
- DBI: [runWDiff] :: WDiff repr v h x -> repr (Diff v h) (Diff v x)
- DBI: abs :: DBI repr => repr (a, h) b -> repr h (a -> b)
- DBI: ap :: Applicative r a => r h (a (x -> y) -> a x -> a y)
- DBI: app :: DBI repr => repr h (a -> b) -> repr h a -> repr h b
- DBI: app2 :: DBI repr => repr h (a1 -> a -> b) -> repr h a1 -> repr h a -> repr h b
- DBI: app3 :: DBI repr => repr h (a2 -> a1 -> a -> b) -> repr h a2 -> repr h a1 -> repr h a -> repr h b
- DBI: appAST :: AST -> AST -> AST
- DBI: bimap :: BiFunctor r p => r h ((a -> b) -> (c -> d) -> p a c -> p b d)
- DBI: bimap2 :: (BiFunctor * repr p, DBI repr) => repr h (a -> b) -> repr h (c -> d) -> repr h (p a c -> p b d)
- DBI: bind :: Monad r m => r h (m a -> (a -> m b) -> m b)
- DBI: bind2 :: Monad repr m => repr h (m a) -> repr h (a -> m b) -> repr h (m b)
- DBI: class Functor r a => Applicative r a
- DBI: class BiFunctor r p
- DBI: class DBI repr where hoas f = abs $ f z com = lam3 $ \ f g x -> app f (app g x) flip = lam3 $ \ f b a -> app2 f a b id = lam $ \ x -> x const = lam2 $ \ x _ -> x scomb = lam3 $ \ f x arg -> app2 f arg (app x arg) dup = lam2 $ \ f x -> app2 f x x let_ = flip1 id
- DBI: class Functor r f
- DBI: class (DBI r, Applicative r m) => Monad r m where join = lam $ \ m -> bind2 m id bind = lam2 $ \ m f -> join1 (app2 map f m)
- DBI: class Monoid r m
- DBI: class NT repr l r
- DBI: class NTS repr l r
- DBI: class ProdCon con l r
- DBI: class RandRange w
- DBI: class Weight w
- DBI: class Monoid repr w => WithDiff repr w
- DBI: com :: DBI repr => repr h ((b -> c) -> (a -> b) -> (a -> c))
- DBI: com2 :: DBI repr => repr h (b -> c) -> repr h (a -> b) -> repr h (a -> c)
- DBI: comb :: x -> Eval h x
- DBI: const :: DBI repr => repr h (a -> b -> a)
- DBI: const1 :: DBI repr => repr h a -> repr h (b -> a)
- DBI: conv :: NT repr l r => repr l t -> repr r t
- DBI: convS :: NTS repr l r => repr l t -> repr r t
- DBI: data AST
- DBI: data Combine l r h x
- DBI: data ImpW repr h x
- DBI: data RunImpW repr h x
- DBI: dup :: DBI repr => repr h ((a -> a -> b) -> (a -> b))
- DBI: flip :: DBI repr => repr h ((a -> b -> c) -> (b -> a -> c))
- DBI: flip1 :: DBI repr => repr h (a -> b -> c) -> repr h (b -> a -> c)
- DBI: flip2 :: DBI repr => repr h (a1 -> a -> c) -> repr h a -> repr h (a1 -> c)
- DBI: hoas :: DBI repr => (repr (a, h) a -> repr (a, h) b) -> repr h (a -> b)
- DBI: id :: DBI repr => repr h (a -> a)
- DBI: instance (DBI.DBI l, DBI.DBI r) => DBI.DBI (DBI.Combine l r)
- DBI: instance (DBI.DBI repr, DBI.NT repr l r) => DBI.NTS repr l (a, r)
- DBI: instance (DBI.RandRange l, DBI.RandRange r) => DBI.RandRange (l, r)
- DBI: instance (DBI.Weight l, DBI.Weight r) => DBI.Weight (l, r)
- DBI: instance (System.Random.Random l, System.Random.Random r) => System.Random.Random (l, r)
- DBI: instance DBI.DBI DBI.Eval
- DBI: instance DBI.DBI DBI.Show
- DBI: instance DBI.DBI repr => DBI.DBI (DBI.WDiff repr v)
- DBI: instance DBI.ProdCon DBI.RandRange l r
- DBI: instance DBI.ProdCon GHC.Show.Show l r
- DBI: instance DBI.ProdCon System.Random.Random l r
- DBI: instance DBI.RandRange ()
- DBI: instance DBI.RandRange GHC.Types.Double
- DBI: instance DBI.Weight ()
- DBI: instance DBI.Weight GHC.Types.Double
- DBI: instance GHC.Show.Show DBI.AST
- DBI: instance System.Random.Random ()
- DBI: instance forall k k1 (repr :: k1 -> k -> *) (l :: k1) (r :: k1). DBI.NTS repr l r => DBI.NT repr l r
- DBI: instance forall k k1 (repr :: k1 -> k -> *) (x :: k1). DBI.NT repr x x
- DBI: join :: Monad r m => r h (m (m a) -> m a)
- DBI: join1 :: Monad repr m => repr h (m (m a)) -> repr h (m a)
- DBI: lam :: forall repr a b h. DBI repr => ((forall k. NT repr (a, h) k => repr k a) -> (repr (a, h)) b) -> repr h (a -> b)
- DBI: lam2 :: forall repr a b c h. DBI repr => ((forall k. NT repr (a, h) k => repr k a) -> (forall k. NT repr (b, (a, h)) k => repr k b) -> (repr (b, (a, h))) c) -> repr h (a -> b -> c)
- DBI: lam3 :: (NT * * repr (a, (b1, (a1, h))) k, NT * * repr (b1, (a1, h)) k1, NT * * repr (a1, h) k2, DBI repr) => (repr k2 a1 -> repr k1 b1 -> repr k a -> repr (a, (b1, (a1, h))) b) -> repr h (a1 -> b1 -> a -> b)
- DBI: lamAST :: String -> AST -> AST
- DBI: let_ :: DBI repr => repr h (a -> (a -> b) -> b)
- DBI: map :: Functor r f => r h ((a -> b) -> (f a -> f b))
- DBI: map1 :: (Functor * repr f, DBI repr) => repr h (a -> b) -> repr h (f a -> f b)
- DBI: map2 :: (Functor * repr f, DBI repr) => repr h (a -> b) -> repr h (f a) -> repr h (f b)
- DBI: name :: String -> Show k k1 h a
- DBI: newtype Eval h x
- DBI: newtype Show h a
- DBI: newtype WDiff repr v h x
- DBI: noEnv :: repr () x -> repr () x
- DBI: plus :: Monoid r m => r h (m -> m -> m)
- DBI: plus2 :: (Monoid * repr b, DBI repr) => repr h b -> repr h b -> repr h b
- DBI: prodCon :: ProdCon con l r => (con l, con r) :- con (l, r)
- DBI: pure :: Applicative r a => r h (x -> a x)
- DBI: randRange :: RandRange w => (Double, Double) -> (w, w)
- DBI: return :: Applicative k r a => r h (x -> a x)
- DBI: runImpW2RunImpWR :: RunImpW repr h x -> RunImpWR repr h x
- DBI: runImpWR2RunImpW :: RunImpWR repr h x -> RunImpW repr h x
- DBI: s :: DBI repr => repr h b -> repr (a, h) b
- DBI: scomb :: DBI repr => repr h ((a -> b -> c) -> (a -> b) -> (a -> c))
- DBI: selfWithDiff :: (DBI repr, WithDiff repr w) => repr h (w -> Diff w w)
- DBI: type RunImpWR repr h x = forall r. (forall w. Weight w => repr h (w -> x) -> r) -> r
- DBI: weightCon :: Weight w => (con (), con Double, ForallV (ProdCon con)) :- con w
- DBI: withDiff :: WithDiff repr w => repr h ((w -> x) -> w -> Diff x w)
- DBI: withDiff1 :: (WithDiff * repr w, DBI repr) => repr h (w -> x) -> repr h (w -> Diff x w)
- DBI: z :: DBI repr => repr (a, h) a
- DBI: zero :: Monoid r m => r h m
- Lang: GWDiff :: (forall v. Vector repr v => Proxy v -> repr (Diff v h) (Diff v x)) -> GWDiff repr h x
- Lang: UnHOAS :: repr h x -> UnHOAS repr h x
- Lang: [runGWDiff] :: GWDiff repr h x -> forall v. Vector repr v => Proxy v -> repr (Diff v h) (Diff v x)
- Lang: [runUnHOAS] :: UnHOAS repr h x -> repr h x
- Lang: class Monoid r g => Group r g where invert = minus1 zero minus = lam2 $ \ x y -> plus2 x (invert1 y)
- Lang: class DBI repr => Lang repr where doubleZero = double 0 doubleOne = double 1 floatZero = float 0 floatOne = float 1 listAppend = lam2 $ \ l r -> fix2 (lam $ \ self -> listMatch2 r (lam2 $ \ a as -> cons2 a (app self as))) l swap = lam $ \ p -> mkProd2 (fst1 p) (zro1 p) curry = lam3 $ \ f a b -> app f (mkProd2 a b) uncurry = lam2 $ \ f p -> app2 f (zro1 p) (fst1 p)
- Lang: class Reify repr x
- Lang: class Group r v => Vector r v where mult = lam2 $ \ x y -> divide2 y (recip1 x) divide = lam2 $ \ x y -> mult2 (recip1 y) x
- Lang: cons :: Lang repr => repr h (a -> [a] -> [a])
- Lang: cons2 :: Lang repr => repr h a1 -> repr h [a1] -> repr h [a1]
- Lang: curry :: Lang repr => repr h (((a, b) -> c) -> (a -> b -> c))
- Lang: divide :: (Vector r v, Lang r) => r h (v -> Double -> v)
- Lang: divide1 :: (Vector repr a, DBI repr) => repr h a -> repr h (Double -> a)
- Lang: divide2 :: (Vector repr b, DBI repr) => repr h b -> repr h Double -> repr h b
- Lang: double :: Lang repr => Double -> repr h Double
- Lang: double2Float :: Lang repr => repr h (Double -> Float)
- Lang: doubleDivide :: Lang repr => repr h (Double -> Double -> Double)
- Lang: doubleExp :: Lang repr => repr h (Double -> Double)
- Lang: doubleExp1 :: Lang repr => repr h Double -> repr h Double
- Lang: doubleMinus :: Lang repr => repr h (Double -> Double -> Double)
- Lang: doubleMult :: Lang repr => repr h (Double -> Double -> Double)
- Lang: doubleOne :: Lang repr => repr h Double
- Lang: doublePlus :: Lang repr => repr h (Double -> Double -> Double)
- Lang: doubleZero :: Lang repr => repr h Double
- Lang: exfalso :: Lang repr => repr h (Void -> a)
- Lang: fix :: Lang repr => repr h ((a -> a) -> a)
- Lang: fix1 :: Lang repr => repr h (b -> b) -> repr h b
- Lang: fix2 :: Lang repr => repr h ((a -> b) -> a -> b) -> repr h a -> repr h b
- Lang: float :: Lang repr => Float -> repr h Float
- Lang: float2Double :: Lang repr => repr h (Float -> Double)
- Lang: float2Double1 :: Lang repr => repr h Float -> repr h Double
- Lang: floatDivide :: Lang repr => repr h (Float -> Float -> Float)
- Lang: floatExp :: Lang repr => repr h (Float -> Float)
- Lang: floatExp1 :: Lang repr => repr h Float -> repr h Float
- Lang: floatMinus :: Lang repr => repr h (Float -> Float -> Float)
- Lang: floatMult :: Lang repr => repr h (Float -> Float -> Float)
- Lang: floatOne :: Lang repr => repr h Float
- Lang: floatPlus :: Lang repr => repr h (Float -> Float -> Float)
- Lang: floatZero :: Lang repr => repr h Float
- Lang: fst :: Lang repr => repr h ((a, b) -> b)
- Lang: fst1 :: Lang repr => repr h (a, b) -> repr h b
- Lang: instance (Lang.Lang l, Lang.Lang r) => Lang.Lang (DBI.Combine l r)
- Lang: instance (Lang.Lang r, DBI.Monoid r w) => DBI.Applicative r (Control.Monad.Trans.Writer.Lazy.Writer w)
- Lang: instance (Lang.Lang r, DBI.Monoid r w) => DBI.Monad r (Control.Monad.Trans.Writer.Lazy.Writer w)
- Lang: instance (Lang.Lang repr, DBI.Monoid repr l, DBI.Monoid repr r) => DBI.Monoid repr (l -> r)
- Lang: instance (Lang.Lang repr, DBI.Monoid repr l, DBI.Monoid repr r) => DBI.Monoid repr (l, r)
- Lang: instance (Lang.Lang repr, DBI.WithDiff repr l, DBI.WithDiff repr r) => DBI.WithDiff repr (l, r)
- Lang: instance (Lang.Lang repr, Lang.Group repr l, Lang.Group repr r) => Lang.Group repr (l -> r)
- Lang: instance (Lang.Lang repr, Lang.Group repr l, Lang.Group repr r) => Lang.Group repr (l, r)
- Lang: instance (Lang.Lang repr, Lang.Reify repr l, Lang.Reify repr r) => Lang.Reify repr (l, r)
- Lang: instance (Lang.Lang repr, Lang.Vector repr l, Lang.Vector repr r) => Lang.Vector repr (l -> r)
- Lang: instance (Lang.Lang repr, Lang.Vector repr l, Lang.Vector repr r) => Lang.Vector repr (l, r)
- Lang: instance (Lang.Vector repr v, Lang.Lang repr) => Lang.Lang (DBI.WDiff repr v)
- Lang: instance DBI.DBI repr => DBI.DBI (Lang.GWDiff repr)
- Lang: instance DBI.DBI repr => DBI.DBI (Lang.UnHOAS repr)
- Lang: instance Lang.Lang DBI.Eval
- Lang: instance Lang.Lang DBI.Show
- Lang: instance Lang.Lang r => DBI.Applicative r GHC.Base.Maybe
- Lang: instance Lang.Lang r => DBI.Applicative r GHC.Types.IO
- Lang: instance Lang.Lang r => DBI.BiFunctor r (,)
- Lang: instance Lang.Lang r => DBI.Functor r (Control.Monad.Trans.Writer.Lazy.Writer w)
- Lang: instance Lang.Lang r => DBI.Functor r GHC.Base.Maybe
- Lang: instance Lang.Lang r => DBI.Functor r GHC.Types.IO
- Lang: instance Lang.Lang r => DBI.Functor r []
- Lang: instance Lang.Lang r => DBI.Monad r GHC.Base.Maybe
- Lang: instance Lang.Lang r => DBI.Monad r GHC.Types.IO
- Lang: instance Lang.Lang r => DBI.Monoid r ()
- Lang: instance Lang.Lang r => DBI.Monoid r GHC.Types.Double
- Lang: instance Lang.Lang r => DBI.Monoid r GHC.Types.Float
- Lang: instance Lang.Lang r => DBI.Monoid r [a]
- Lang: instance Lang.Lang r => Lang.Group r ()
- Lang: instance Lang.Lang r => Lang.Group r GHC.Types.Double
- Lang: instance Lang.Lang r => Lang.Group r GHC.Types.Float
- Lang: instance Lang.Lang r => Lang.Vector r ()
- Lang: instance Lang.Lang r => Lang.Vector r GHC.Types.Double
- Lang: instance Lang.Lang r => Lang.Vector r GHC.Types.Float
- Lang: instance Lang.Lang repr => DBI.DBI (DBI.ImpW repr)
- Lang: instance Lang.Lang repr => DBI.ProdCon (DBI.Monoid repr) l r
- Lang: instance Lang.Lang repr => DBI.ProdCon (DBI.WithDiff repr) l r
- Lang: instance Lang.Lang repr => DBI.ProdCon (Lang.Reify repr) l r
- Lang: instance Lang.Lang repr => DBI.ProdCon (Lang.Vector repr) l r
- Lang: instance Lang.Lang repr => DBI.WithDiff repr ()
- Lang: instance Lang.Lang repr => DBI.WithDiff repr GHC.Types.Double
- Lang: instance Lang.Lang repr => Lang.Lang (DBI.ImpW repr)
- Lang: instance Lang.Lang repr => Lang.Lang (Lang.GWDiff repr)
- Lang: instance Lang.Lang repr => Lang.Lang (Lang.UnHOAS repr)
- Lang: instance Lang.Lang repr => Lang.Reify repr ()
- Lang: instance Lang.Lang repr => Lang.Reify repr GHC.Types.Double
- Lang: invert :: (Group r g, Lang r) => r h (g -> g)
- Lang: invert1 :: (Group repr b, DBI repr) => repr h b -> repr h b
- Lang: ioBind :: Lang repr => repr h (IO a -> (a -> IO b) -> IO b)
- Lang: ioBind2 :: Lang repr => repr h (IO a) -> repr h (a -> IO b) -> repr h (IO b)
- Lang: ioMap :: Lang repr => repr h ((a -> b) -> IO a -> IO b)
- Lang: ioRet :: Lang repr => repr h (a -> IO a)
- Lang: just :: Lang repr => repr h (a -> Maybe a)
- Lang: left :: Lang repr => repr h (a -> Either a b)
- Lang: listAppend :: Lang repr => repr h ([a] -> [a] -> [a])
- Lang: listMatch :: Lang repr => repr h (b -> (a -> [a] -> b) -> [a] -> b)
- Lang: listMatch2 :: Lang repr => repr h a1 -> repr h (a -> [a] -> a1) -> repr h ([a] -> a1)
- Lang: minus :: (Group r g, Lang r) => r h (g -> g -> g)
- Lang: minus1 :: (Group repr a, DBI repr) => repr h a -> repr h (a -> a)
- Lang: minus2 :: (Group repr b, DBI repr) => repr h b -> repr h b -> repr h b
- Lang: mkProd :: Lang repr => repr h (a -> b -> (a, b))
- Lang: mkProd1 :: Lang repr => repr h a -> repr h (b -> (a, b))
- Lang: mkProd2 :: Lang repr => repr h a1 -> repr h a -> repr h (a1, a)
- Lang: mult :: (Vector r v, Lang r) => r h (Double -> v -> v)
- Lang: mult1 :: (Vector repr v, DBI repr) => repr h Double -> repr h (v -> v)
- Lang: mult2 :: (Vector repr b, DBI repr) => repr h Double -> repr h b -> repr h b
- Lang: newtype GWDiff repr h x
- Lang: newtype UnHOAS repr h x
- Lang: nil :: Lang repr => repr h [a]
- Lang: nothing :: Lang repr => repr h (Maybe a)
- Lang: optionMatch :: Lang repr => repr h (b -> (a -> b) -> Maybe a -> b)
- Lang: optionMatch2 :: Lang repr => repr h a1 -> repr h (a -> a1) -> repr h (Maybe a -> a1)
- Lang: optionMatch3 :: Lang repr => repr h b -> repr h (a -> b) -> repr h (Maybe a) -> repr h b
- Lang: recip :: Lang repr => repr h (Double -> Double)
- Lang: recip1 :: Lang repr => repr h Double -> repr h Double
- Lang: reify :: Reify repr x => x -> repr h x
- Lang: right :: Lang repr => repr h (b -> Either a b)
- Lang: runImpW :: forall repr h x. Lang repr => ImpW repr h x -> RunImpW repr h x
- Lang: runWriter :: Lang repr => repr h (Writer w a -> (a, w))
- Lang: runWriter1 :: Lang repr => repr h (Writer w a) -> repr h (a, w)
- Lang: sumMatch :: Lang repr => repr h ((a -> c) -> (b -> c) -> Either a b -> c)
- Lang: swap :: Lang repr => repr h ((l, r) -> (r, l))
- Lang: uncurry :: Lang repr => repr h ((a -> b -> c) -> ((a, b) -> c))
- Lang: uncurry1 :: Lang repr => repr h (a -> b -> c) -> repr h ((a, b) -> c)
- Lang: unit :: Lang repr => repr h ()
- Lang: writer :: Lang repr => repr h ((a, w) -> Writer w a)
- Lang: writer1 :: Lang repr => repr h (a, w) -> repr h (Writer w a)
- Lang: zro :: Lang repr => repr h ((a, b) -> a)
- Lang: zro1 :: Lang repr => repr h (b1, b) -> repr h b1
- Poly: comp :: Lang repr => repr h (Double -> Double)
- Poly: l2 :: Lang repr => repr h (Double -> Double)
- Poly: main :: IO ()
- Poly: poly :: forall repr h. Lang repr => repr h (Double -> Double)
- Poly: solve :: forall m. Monad m => (AST -> m ()) -> (Integer -> Double -> m ()) -> m Double
- Util: isSquare :: Integral a => a -> Bool
- Util: vars :: [[Char]]
- Xor: dataset :: Lang repr => repr h [((Double, Double), Double)]
- Xor: eval :: Lang repr => repr h (XOR -> ((Double, Double), Double) -> Double)
- Xor: findXor :: forall g m. (RandomGen g, Monad m) => g -> (AST -> m ()) -> (Int -> Double -> String -> m ()) -> m XOR
- Xor: hidden :: Lang repr => ImpW * repr h ((Double, Double) -> ((Double, Double), (Double, Double)))
- Xor: l2 :: Lang repr => repr h (Double -> Double -> Double)
- Xor: l22 :: Lang repr => repr h Double -> repr h Double -> repr h Double
- Xor: loss :: Lang repr => repr h (XOR -> Double)
- Xor: main :: IO ()
- Xor: neuron :: Lang repr => ImpW repr h ((Double, Double) -> Double)
- Xor: neuron1 :: Lang repr => ImpW * repr h (Double, Double) -> ImpW * repr h Double
- Xor: scaleAdd :: Lang repr => ImpW repr h ((Double, Double) -> Double)
- Xor: sigmoid :: Lang repr => repr h (Double -> Double)
- Xor: sigmoid1 :: Lang repr => repr h Double -> repr h Double
- Xor: type XOR = (Double, Double) -> Double
- Xor: weight :: Lang repr => ImpW repr h Double
- Xor: withBias :: Lang repr => ImpW repr h (Double -> Double)
- Xor: xor :: Lang repr => ImpW repr h XOR
+ DDF.Bool: bool :: Bool r => Bool -> r h Bool
+ DDF.Bool: class DBI r => Bool r
+ DDF.Bool: ite :: Bool r => r h (a -> a -> Bool -> a)
+ DDF.Combine: Combine :: (l h x) -> (r h x) -> Combine l r h x
+ DDF.Combine: data Combine l r h x
+ DDF.Combine: instance (DDF.Bool.Bool l, DDF.Bool.Bool r) => DDF.Bool.Bool (DDF.Combine.Combine l r)
+ DDF.Combine: instance (DDF.DBI.DBI l, DDF.DBI.DBI r) => DDF.DBI.DBI (DDF.Combine.Combine l r)
+ DDF.Combine: instance (DDF.Lang.Lang l, DDF.Lang.Lang r) => DDF.Lang.Lang (DDF.Combine.Combine l r)
+ DDF.DBI: ImpW :: (repr h (w -> x)) -> ImpW repr h x
+ DDF.DBI: NoImpW :: (repr h x) -> ImpW repr h x
+ DDF.DBI: RunImpW :: (repr h (w -> x)) -> RunImpW repr h x
+ DDF.DBI: WDiff :: repr (Diff v h) (Diff v x) -> WDiff repr v h x
+ DDF.DBI: [runWDiff] :: WDiff repr v h x -> repr (Diff v h) (Diff v x)
+ DDF.DBI: abs :: DBI repr => repr (a, h) b -> repr h (a -> b)
+ DDF.DBI: ap :: Applicative r a => r h (a (x -> y) -> a x -> a y)
+ DDF.DBI: app :: DBI repr => repr h (a -> b) -> repr h a -> repr h b
+ DDF.DBI: app2 :: DBI repr => repr h (a1 -> a -> b) -> repr h a1 -> repr h a -> repr h b
+ DDF.DBI: app3 :: DBI repr => repr h (a2 -> a1 -> a -> b) -> repr h a2 -> repr h a1 -> repr h a -> repr h b
+ DDF.DBI: bimap :: BiFunctor r p => r h ((a -> b) -> (c -> d) -> p a c -> p b d)
+ DDF.DBI: bimap2 :: (BiFunctor * repr p, DBI repr) => repr h (a -> b) -> repr h (c -> d) -> repr h (p a c -> p b d)
+ DDF.DBI: bimap3 :: (BiFunctor * repr p, DBI repr) => repr h (a -> b) -> repr h (c -> d) -> repr h (p a c) -> repr h (p b d)
+ DDF.DBI: bind :: Monad r m => r h (m a -> (a -> m b) -> m b)
+ DDF.DBI: bind2 :: Monad repr m => repr h (m a) -> repr h (a -> m b) -> repr h (m b)
+ DDF.DBI: class Functor r a => Applicative r a
+ DDF.DBI: class BiFunctor r p
+ DDF.DBI: class DBI repr => ConvDiff repr w where toDiff _ = toDiffBy1 @repr @w @x zero fromDiff _ = fromDiffBy1 @repr @w @x zero
+ DDF.DBI: class DBI (repr :: * -> * -> *) where hoas f = abs $ f z com = lam3 $ \ f g x -> app f (app g x) flip = lam3 $ \ f b a -> app2 f a b id = lam $ \ x -> x const = lam2 $ \ x _ -> x scomb = lam3 $ \ f x arg -> app2 f arg (app x arg) dup = lam2 $ \ f x -> app2 f x x let_ = flip1 id
+ DDF.DBI: class Functor r f
+ DDF.DBI: class (DBI r, Applicative r m) => Monad r m where join = lam $ \ m -> bind2 m id bind = lam2 $ \ m f -> join1 (app2 map f m)
+ DDF.DBI: class Monoid r m
+ DDF.DBI: class NT repr l r
+ DDF.DBI: class NTS repr l r
+ DDF.DBI: class ProdCon con l r
+ DDF.DBI: class Weight w
+ DDF.DBI: class Monoid repr w => WithDiff repr w
+ DDF.DBI: com :: DBI repr => repr h ((b -> c) -> (a -> b) -> (a -> c))
+ DDF.DBI: com2 :: DBI repr => repr h (b -> c) -> repr h (a -> b) -> repr h (a -> c)
+ DDF.DBI: const :: DBI repr => repr h (a -> b -> a)
+ DDF.DBI: const1 :: DBI repr => repr h a -> repr h (b -> a)
+ DDF.DBI: conv :: NT repr l r => repr l t -> repr r t
+ DDF.DBI: convS :: NTS repr l r => repr l t -> repr r t
+ DDF.DBI: data ImpW repr h x
+ DDF.DBI: data RunImpW repr h x
+ DDF.DBI: dup :: DBI repr => repr h ((a -> a -> b) -> (a -> b))
+ DDF.DBI: flip :: DBI repr => repr h ((a -> b -> c) -> (b -> a -> c))
+ DDF.DBI: flip1 :: DBI repr => repr h (a -> b -> c) -> repr h (b -> a -> c)
+ DDF.DBI: flip2 :: DBI repr => repr h (a1 -> a -> c) -> repr h a -> repr h (a1 -> c)
+ DDF.DBI: fromDiff :: forall h x. (ConvDiff repr w, Monoid repr x) => Proxy x -> repr h (Diff x w -> w)
+ DDF.DBI: fromDiffBy :: ConvDiff repr w => repr h (x -> Diff x w -> w)
+ DDF.DBI: fromDiffBy1 :: forall repr w x h. ConvDiff repr w => repr h x -> repr h (Diff x w -> w)
+ DDF.DBI: hoas :: DBI repr => (repr (a, h) a -> repr (a, h) b) -> repr h (a -> b)
+ DDF.DBI: id :: DBI repr => repr h (a -> a)
+ DDF.DBI: instance (DDF.DBI.DBI repr, DDF.DBI.NT repr l r) => DDF.DBI.NTS repr l (a, r)
+ DDF.DBI: instance (DDF.DBI.Weight l, DDF.DBI.Weight r) => DDF.DBI.Weight (l, r)
+ DDF.DBI: instance DDF.DBI.DBI repr => DDF.DBI.DBI (DDF.DBI.WDiff repr v)
+ DDF.DBI: instance DDF.DBI.ProdCon DDF.Util.RandRange l r
+ DDF.DBI: instance DDF.DBI.ProdCon GHC.Show.Show l r
+ DDF.DBI: instance DDF.DBI.ProdCon System.Random.Random l r
+ DDF.DBI: instance DDF.DBI.Weight ()
+ DDF.DBI: instance DDF.DBI.Weight GHC.Types.Double
+ DDF.DBI: instance forall k k1 (repr :: k1 -> k -> *) (l :: k1) (r :: k1). DDF.DBI.NTS repr l r => DDF.DBI.NT repr l r
+ DDF.DBI: instance forall k k1 (repr :: k1 -> k -> *) (x :: k1). DDF.DBI.NT repr x x
+ DDF.DBI: join :: Monad r m => r h (m (m a) -> m a)
+ DDF.DBI: join1 :: Monad repr m => repr h (m (m a)) -> repr h (m a)
+ DDF.DBI: lam :: forall repr a b h. DBI repr => ((forall k. NT repr (a, h) k => repr k a) -> (repr (a, h)) b) -> repr h (a -> b)
+ DDF.DBI: lam2 :: forall repr a b c h. DBI repr => ((forall k. NT repr (a, h) k => repr k a) -> (forall k. NT repr (b, (a, h)) k => repr k b) -> (repr (b, (a, h))) c) -> repr h (a -> b -> c)
+ DDF.DBI: lam3 :: (NT * * repr (a, (b1, (a1, h))) k, NT * * repr (b1, (a1, h)) k1, NT * * repr (a1, h) k2, DBI repr) => (repr k2 a1 -> repr k1 b1 -> repr k a -> repr (a, (b1, (a1, h))) b) -> repr h (a1 -> b1 -> a -> b)
+ DDF.DBI: let_ :: DBI repr => repr h (a -> (a -> b) -> b)
+ DDF.DBI: let_2 :: DBI repr => repr h a -> repr h (a -> b) -> repr h b
+ DDF.DBI: map :: Functor r f => r h ((a -> b) -> (f a -> f b))
+ DDF.DBI: map1 :: (Functor * repr f, DBI repr) => repr h (a -> b) -> repr h (f a -> f b)
+ DDF.DBI: map2 :: (Functor * repr f, DBI repr) => repr h (a -> b) -> repr h (f a) -> repr h (f b)
+ DDF.DBI: newtype WDiff repr v h x
+ DDF.DBI: noEnv :: repr () x -> repr () x
+ DDF.DBI: plus :: Monoid r m => r h (m -> m -> m)
+ DDF.DBI: plus2 :: (Monoid * repr b, DBI repr) => repr h b -> repr h b -> repr h b
+ DDF.DBI: prodCon :: ProdCon con l r => (con l, con r) :- con (l, r)
+ DDF.DBI: pure :: Applicative r a => r h (x -> a x)
+ DDF.DBI: return :: Applicative k r a => r h (x -> a x)
+ DDF.DBI: runImpW2RunImpWR :: RunImpW repr h x -> RunImpWR repr h x
+ DDF.DBI: runImpWR2RunImpW :: RunImpWR repr h x -> RunImpW repr h x
+ DDF.DBI: s :: DBI repr => repr h b -> repr (a, h) b
+ DDF.DBI: scomb :: DBI repr => repr h ((a -> b -> c) -> (a -> b) -> (a -> c))
+ DDF.DBI: selfWithDiff :: (DBI repr, WithDiff repr w) => repr h (w -> Diff w w)
+ DDF.DBI: toDiff :: forall h x. (ConvDiff repr w, Monoid repr x) => Proxy x -> repr h (w -> Diff x w)
+ DDF.DBI: toDiffBy :: forall h x. ConvDiff repr w => repr h (x -> w -> Diff x w)
+ DDF.DBI: toDiffBy1 :: forall repr w x h. ConvDiff repr w => repr h x -> repr h (w -> Diff x w)
+ DDF.DBI: type RunImpWR repr h x = forall r. (forall w. Weight w => repr h (w -> x) -> r) -> r
+ DDF.DBI: weightCon :: Weight w => (con (), con Float, con Double, ForallV (ProdCon con)) :- con w
+ DDF.DBI: withDiff :: WithDiff repr w => repr h ((w -> x) -> w -> Diff x w)
+ DDF.DBI: withDiff1 :: (WithDiff * repr w, DBI repr) => repr h (w -> x) -> repr h (w -> Diff x w)
+ DDF.DBI: z :: DBI repr => repr (a, h) a
+ DDF.DBI: zero :: Monoid r m => r h m
+ DDF.Eval: Eval :: (h -> x) -> Eval h x
+ DDF.Eval: [runEval] :: Eval h x -> h -> x
+ DDF.Eval: comb :: x -> Eval h x
+ DDF.Eval: instance DDF.Bool.Bool DDF.Eval.Eval
+ DDF.Eval: instance DDF.DBI.DBI DDF.Eval.Eval
+ DDF.Eval: instance DDF.Lang.Lang DDF.Eval.Eval
+ DDF.Eval: newtype Eval h x
+ DDF.GWDiff: GWDiff :: (forall v. Vector repr v => Proxy v -> repr (Diff v h) (Diff v x)) -> GWDiff repr h x
+ DDF.GWDiff: [runGWDiff] :: GWDiff repr h x -> forall v. Vector repr v => Proxy v -> repr (Diff v h) (Diff v x)
+ DDF.GWDiff: instance DDF.Bool.Bool r => DDF.Bool.Bool (DDF.GWDiff.GWDiff r)
+ DDF.GWDiff: instance DDF.DBI.DBI repr => DDF.DBI.DBI (DDF.GWDiff.GWDiff repr)
+ DDF.GWDiff: instance DDF.Lang.Lang repr => DDF.Lang.Lang (DDF.GWDiff.GWDiff repr)
+ DDF.GWDiff: newtype GWDiff repr h x
+ DDF.Lang: class Monoid r g => Group r g where invert = minus1 zero minus = lam2 $ \ x y -> plus2 x (invert1 y)
+ DDF.Lang: class Bool repr => Lang repr where doubleZero = double 0 doubleOne = double 1 floatZero = float 0 floatOne = float 1 listAppend = lam2 $ \ l r -> fix2 (lam $ \ self -> listMatch2 r (lam2 $ \ a as -> cons2 a (app self as))) l swap = lam $ \ p -> mkProd2 (fst1 p) (zro1 p) curry = lam3 $ \ f a b -> app f (mkProd2 a b) uncurry = lam2 $ \ f p -> app2 f (zro1 p) (fst1 p) undefined = fix1 id
+ DDF.Lang: class Reify repr x
+ DDF.Lang: class Group r v => Vector r v where mult = lam2 $ \ x y -> divide2 y (recip1 x) divide = lam2 $ \ x y -> mult2 (recip1 y) x
+ DDF.Lang: cons :: Lang repr => repr h (a -> [a] -> [a])
+ DDF.Lang: cons2 :: Lang repr => repr h a1 -> repr h [a1] -> repr h [a1]
+ DDF.Lang: curry :: Lang repr => repr h (((a, b) -> c) -> (a -> b -> c))
+ DDF.Lang: divide :: (Vector r v, Lang r) => r h (v -> Double -> v)
+ DDF.Lang: divide1 :: (Vector repr a, DBI repr) => repr h a -> repr h (Double -> a)
+ DDF.Lang: divide2 :: (Vector repr b, DBI repr) => repr h b -> repr h Double -> repr h b
+ DDF.Lang: double :: Lang repr => Double -> repr h Double
+ DDF.Lang: double2Float :: Lang repr => repr h (Double -> Float)
+ DDF.Lang: doubleDivide :: Lang repr => repr h (Double -> Double -> Double)
+ DDF.Lang: doubleExp :: Lang repr => repr h (Double -> Double)
+ DDF.Lang: doubleExp1 :: Lang repr => repr h Double -> repr h Double
+ DDF.Lang: doubleMinus :: Lang repr => repr h (Double -> Double -> Double)
+ DDF.Lang: doubleMult :: Lang repr => repr h (Double -> Double -> Double)
+ DDF.Lang: doubleOne :: Lang repr => repr h Double
+ DDF.Lang: doublePlus :: Lang repr => repr h (Double -> Double -> Double)
+ DDF.Lang: doubleZero :: Lang repr => repr h Double
+ DDF.Lang: exfalso :: Lang repr => repr h (Void -> a)
+ DDF.Lang: fix :: Lang repr => repr h ((a -> a) -> a)
+ DDF.Lang: fix1 :: Lang repr => repr h (b -> b) -> repr h b
+ DDF.Lang: fix2 :: Lang repr => repr h ((a -> b) -> a -> b) -> repr h a -> repr h b
+ DDF.Lang: float :: Lang repr => Float -> repr h Float
+ DDF.Lang: float2Double :: Lang repr => repr h (Float -> Double)
+ DDF.Lang: float2Double1 :: Lang repr => repr h Float -> repr h Double
+ DDF.Lang: floatDivide :: Lang repr => repr h (Float -> Float -> Float)
+ DDF.Lang: floatExp :: Lang repr => repr h (Float -> Float)
+ DDF.Lang: floatExp1 :: Lang repr => repr h Float -> repr h Float
+ DDF.Lang: floatMinus :: Lang repr => repr h (Float -> Float -> Float)
+ DDF.Lang: floatMult :: Lang repr => repr h (Float -> Float -> Float)
+ DDF.Lang: floatOne :: Lang repr => repr h Float
+ DDF.Lang: floatPlus :: Lang repr => repr h (Float -> Float -> Float)
+ DDF.Lang: floatZero :: Lang repr => repr h Float
+ DDF.Lang: fst :: Lang repr => repr h ((a, b) -> b)
+ DDF.Lang: fst1 :: Lang repr => repr h (a, b) -> repr h b
+ DDF.Lang: instance (DDF.Bool.Bool r, DDF.Lang.Vector r v) => DDF.Bool.Bool (DDF.DBI.WDiff r v)
+ DDF.Lang: instance (DDF.Lang.Lang r, DDF.DBI.Monoid r w) => DDF.DBI.Applicative r (Control.Monad.Trans.Writer.Lazy.Writer w)
+ DDF.Lang: instance (DDF.Lang.Lang r, DDF.DBI.Monoid r w) => DDF.DBI.Monad r (Control.Monad.Trans.Writer.Lazy.Writer w)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.ConvDiff repr l) => DDF.DBI.ConvDiff repr [l]
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.ConvDiff repr l, DDF.DBI.ConvDiff repr r) => DDF.DBI.ConvDiff repr (Data.Either.Either l r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.ConvDiff repr l, DDF.DBI.ConvDiff repr r) => DDF.DBI.ConvDiff repr (l -> r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.ConvDiff repr l, DDF.DBI.ConvDiff repr r) => DDF.DBI.ConvDiff repr (l, r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.Monoid repr l, DDF.DBI.Monoid repr r) => DDF.DBI.Monoid repr (l, r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.Monoid repr v) => DDF.DBI.Monoid repr (GHC.Types.Double -> v)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.DBI.WithDiff repr l, DDF.DBI.WithDiff repr r) => DDF.DBI.WithDiff repr (l, r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.Lang.Group repr l, DDF.Lang.Group repr r) => DDF.Lang.Group repr (l, r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.Lang.Group repr v) => DDF.Lang.Group repr (GHC.Types.Double -> v)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.Lang.Reify repr l, DDF.Lang.Reify repr r) => DDF.Lang.Reify repr (l, r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.Lang.Vector repr l, DDF.Lang.Vector repr r) => DDF.Lang.Vector repr (l, r)
+ DDF.Lang: instance (DDF.Lang.Lang repr, DDF.Lang.Vector repr v) => DDF.Lang.Vector repr (GHC.Types.Double -> v)
+ DDF.Lang: instance (DDF.Lang.Vector repr v, DDF.Lang.Lang repr) => DDF.Lang.Lang (DDF.DBI.WDiff repr v)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Bool.Bool (DDF.DBI.ImpW r)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Applicative r (Control.Monad.Trans.State.Lazy.State l)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Applicative r GHC.Base.Maybe
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Applicative r GHC.Types.IO
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.BiFunctor r (,)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.BiFunctor r Data.Either.Either
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Functor r (Control.Monad.Trans.State.Lazy.State l)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Functor r (Control.Monad.Trans.Writer.Lazy.Writer w)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Functor r GHC.Base.Maybe
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Functor r GHC.Types.IO
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Functor r []
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monad r (Control.Monad.Trans.State.Lazy.State l)
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monad r GHC.Base.Maybe
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monad r GHC.Types.IO
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monoid r ()
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monoid r GHC.Types.Double
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monoid r GHC.Types.Float
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.DBI.Monoid r [a]
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Lang.Group r ()
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Lang.Group r GHC.Types.Double
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Lang.Group r GHC.Types.Float
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Lang.Vector r ()
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Lang.Vector r GHC.Types.Double
+ DDF.Lang: instance DDF.Lang.Lang r => DDF.Lang.Vector r GHC.Types.Float
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ConvDiff repr ()
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ConvDiff repr GHC.Types.Double
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ConvDiff repr GHC.Types.Float
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.DBI (DDF.DBI.ImpW repr)
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ProdCon (DDF.DBI.Monoid repr) l r
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ProdCon (DDF.DBI.WithDiff repr) l r
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ProdCon (DDF.Lang.Reify repr) l r
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.ProdCon (DDF.Lang.Vector repr) l r
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.WithDiff repr ()
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.WithDiff repr GHC.Types.Double
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.DBI.WithDiff repr GHC.Types.Float
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.Lang.Lang (DDF.DBI.ImpW repr)
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.Lang.Reify repr ()
+ DDF.Lang: instance DDF.Lang.Lang repr => DDF.Lang.Reify repr GHC.Types.Double
+ DDF.Lang: invert :: (Group r g, Lang r) => r h (g -> g)
+ DDF.Lang: invert1 :: (Group repr b, DBI repr) => repr h b -> repr h b
+ DDF.Lang: ioBind :: Lang repr => repr h (IO a -> (a -> IO b) -> IO b)
+ DDF.Lang: ioBind2 :: Lang repr => repr h (IO a) -> repr h (a -> IO b) -> repr h (IO b)
+ DDF.Lang: ioMap :: Lang repr => repr h ((a -> b) -> IO a -> IO b)
+ DDF.Lang: ioRet :: Lang repr => repr h (a -> IO a)
+ DDF.Lang: just :: Lang repr => repr h (a -> Maybe a)
+ DDF.Lang: left :: Lang repr => repr h (a -> Either a b)
+ DDF.Lang: listAppend :: Lang repr => repr h ([a] -> [a] -> [a])
+ DDF.Lang: listMatch :: Lang repr => repr h (b -> (a -> [a] -> b) -> [a] -> b)
+ DDF.Lang: listMatch2 :: Lang repr => repr h a1 -> repr h (a -> [a] -> a1) -> repr h ([a] -> a1)
+ DDF.Lang: minus :: (Group r g, Lang r) => r h (g -> g -> g)
+ DDF.Lang: minus1 :: (Group repr a, DBI repr) => repr h a -> repr h (a -> a)
+ DDF.Lang: minus2 :: (Group repr b, DBI repr) => repr h b -> repr h b -> repr h b
+ DDF.Lang: mkProd :: Lang repr => repr h (a -> b -> (a, b))
+ DDF.Lang: mkProd1 :: Lang repr => repr h a -> repr h (b -> (a, b))
+ DDF.Lang: mkProd2 :: Lang repr => repr h a1 -> repr h a -> repr h (a1, a)
+ DDF.Lang: mult :: (Vector r v, Lang r) => r h (Double -> v -> v)
+ DDF.Lang: mult1 :: (Vector repr v, DBI repr) => repr h Double -> repr h (v -> v)
+ DDF.Lang: mult2 :: (Vector repr b, DBI repr) => repr h Double -> repr h b -> repr h b
+ DDF.Lang: nil :: Lang repr => repr h [a]
+ DDF.Lang: nothing :: Lang repr => repr h (Maybe a)
+ DDF.Lang: optionMatch :: Lang repr => repr h (b -> (a -> b) -> Maybe a -> b)
+ DDF.Lang: optionMatch2 :: Lang repr => repr h a1 -> repr h (a -> a1) -> repr h (Maybe a -> a1)
+ DDF.Lang: optionMatch3 :: Lang repr => repr h b -> repr h (a -> b) -> repr h (Maybe a) -> repr h b
+ DDF.Lang: recip :: Lang repr => repr h (Double -> Double)
+ DDF.Lang: recip1 :: Lang repr => repr h Double -> repr h Double
+ DDF.Lang: reify :: Reify repr x => x -> repr h x
+ DDF.Lang: right :: Lang repr => repr h (b -> Either a b)
+ DDF.Lang: runImpW :: forall repr h x. Lang repr => ImpW repr h x -> RunImpW repr h x
+ DDF.Lang: runState :: Lang repr => repr h (State l r -> (l -> (r, l)))
+ DDF.Lang: runState1 :: Lang repr => repr h (State l r) -> repr h (l -> (r, l))
+ DDF.Lang: runState2 :: Lang repr => repr h (State a r) -> repr h a -> repr h (r, a)
+ DDF.Lang: runWriter :: Lang repr => repr h (Writer w a -> (a, w))
+ DDF.Lang: runWriter1 :: Lang repr => repr h (Writer w a) -> repr h (a, w)
+ DDF.Lang: state :: Lang repr => repr h ((l -> (r, l)) -> State l r)
+ DDF.Lang: state1 :: Lang repr => repr h (l -> (r, l)) -> repr h (State l r)
+ DDF.Lang: sumMatch :: Lang repr => repr h ((a -> c) -> (b -> c) -> Either a b -> c)
+ DDF.Lang: sumMatch2 :: Lang repr => repr h (a -> c) -> repr h (b -> c) -> repr h (Either a b -> c)
+ DDF.Lang: swap :: Lang repr => repr h ((l, r) -> (r, l))
+ DDF.Lang: uncurry :: Lang repr => repr h ((a -> b -> c) -> ((a, b) -> c))
+ DDF.Lang: uncurry1 :: Lang repr => repr h (a -> b -> c) -> repr h ((a, b) -> c)
+ DDF.Lang: undefined :: Lang repr => repr h a
+ DDF.Lang: unit :: Lang repr => repr h ()
+ DDF.Lang: writer :: Lang repr => repr h ((a, w) -> Writer w a)
+ DDF.Lang: writer1 :: Lang repr => repr h (a, w) -> repr h (Writer w a)
+ DDF.Lang: zro :: Lang repr => repr h ((a, b) -> a)
+ DDF.Lang: zro1 :: Lang repr => repr h (b1, b) -> repr h b1
+ DDF.Poly: comp :: Lang repr => repr h (Double -> Double)
+ DDF.Poly: l2 :: Lang repr => repr h (Double -> Double)
+ DDF.Poly: main :: IO ()
+ DDF.Poly: poly :: forall repr h. Lang repr => repr h (Double -> Double)
+ DDF.Poly: solve :: forall m. Monad m => (AST -> m ()) -> (Integer -> Double -> m ()) -> m Double
+ DDF.Show: App :: String -> AST -> [AST] -> AST
+ DDF.Show: Lam :: String -> [String] -> AST -> AST
+ DDF.Show: Leaf :: String -> AST
+ DDF.Show: Show :: ([String] -> Int -> AST) -> Show h a
+ DDF.Show: [runShow] :: Show h a -> [String] -> Int -> AST
+ DDF.Show: appAST :: AST -> AST -> AST
+ DDF.Show: data AST
+ DDF.Show: instance DDF.Bool.Bool DDF.Show.Show
+ DDF.Show: instance DDF.DBI.DBI DDF.Show.Show
+ DDF.Show: instance DDF.Lang.Lang DDF.Show.Show
+ DDF.Show: instance GHC.Show.Show DDF.Show.AST
+ DDF.Show: lamAST :: String -> AST -> AST
+ DDF.Show: name :: String -> Show h a
+ DDF.Show: newtype Show h a
+ DDF.UnHOAS: UnHOAS :: repr h x -> UnHOAS repr h x
+ DDF.UnHOAS: [runUnHOAS] :: UnHOAS repr h x -> repr h x
+ DDF.UnHOAS: instance DDF.Bool.Bool r => DDF.Bool.Bool (DDF.UnHOAS.UnHOAS r)
+ DDF.UnHOAS: instance DDF.DBI.DBI repr => DDF.DBI.DBI (DDF.UnHOAS.UnHOAS repr)
+ DDF.UnHOAS: instance DDF.Lang.Lang repr => DDF.Lang.Lang (DDF.UnHOAS.UnHOAS repr)
+ DDF.UnHOAS: newtype UnHOAS repr h x
+ DDF.Util: class RandRange w
+ DDF.Util: instance (DDF.Util.RandRange l, DDF.Util.RandRange r) => DDF.Util.RandRange (l, r)
+ DDF.Util: instance (System.Random.Random l, System.Random.Random r) => System.Random.Random (l, r)
+ DDF.Util: instance DDF.Util.RandRange ()
+ DDF.Util: instance DDF.Util.RandRange GHC.Types.Double
+ DDF.Util: instance DDF.Util.RandRange GHC.Types.Float
+ DDF.Util: instance System.Random.Random ()
+ DDF.Util: isSquare :: Integral a => a -> Bool
+ DDF.Util: randRange :: RandRange w => (Double, Double) -> (w, w)
+ DDF.Util: vars :: [[Char]]
+ DDF.Xor: dataset :: Lang repr => repr h [((Double, Double), Double)]
+ DDF.Xor: eval :: Lang repr => repr h (XOR -> ((Double, Double), Double) -> Double)
+ DDF.Xor: findXor :: forall g m. (RandomGen g, Monad m) => g -> (AST -> m ()) -> (Int -> Double -> String -> m ()) -> m XOR
+ DDF.Xor: hidden :: Lang repr => ImpW * repr h ((Double, Double) -> ((Double, Double), (Double, Double)))
+ DDF.Xor: l2 :: Lang repr => repr h (Double -> Double -> Double)
+ DDF.Xor: l22 :: Lang repr => repr h Double -> repr h Double -> repr h Double
+ DDF.Xor: loss :: Lang repr => repr h (XOR -> Double)
+ DDF.Xor: main :: IO ()
+ DDF.Xor: neuron :: Lang repr => ImpW repr h ((Double, Double) -> Double)
+ DDF.Xor: neuron1 :: Lang repr => ImpW * repr h (Double, Double) -> ImpW * repr h Double
+ DDF.Xor: scaleAdd :: Lang repr => ImpW repr h ((Double, Double) -> Double)
+ DDF.Xor: sigmoid :: Lang repr => repr h (Double -> Double)
+ DDF.Xor: sigmoid1 :: Lang repr => repr h Double -> repr h Double
+ DDF.Xor: type XOR = (Double, Double) -> Double
+ DDF.Xor: weight :: Lang repr => ImpW repr h Double
+ DDF.Xor: withBias :: Lang repr => ImpW repr h (Double -> Double)
+ DDF.Xor: xor :: Lang repr => ImpW repr h XOR
Files
- DDF/Bool.hs +9/−0
- DDF/Combine.hs +57/−0
- DDF/DBI.hs +185/−0
- DDF/Eval.hs +72/−0
- DDF/GWDiff.hs +70/−0
- DDF/ImportMeta.hs +6/−0
- DDF/Lang.hs +442/−0
- DDF/Poly.lhs +108/−0
- DDF/Show.hs +74/−0
- DDF/UnHOAS.hs +55/−0
- DDF/Util.hs +43/−0
- DDF/Xor.lhs +129/−0
- DeepDarkFantasy.cabal +13/−7
- lib/DBI.hs +0/−246
- lib/Lang.hs +0/−587
- lib/Poly.lhs +0/−107
- lib/Util.hs +0/−6
- lib/Xor.lhs +0/−127
- test/TestPoly.hs +1/−1
- test/TestXor.hs +1/−2
+ DDF/Bool.hs view
@@ -0,0 +1,9 @@+{-# LANGUAGE NoImplicitPrelude #-}+module DDF.Bool (module DDF.Bool, module DDF.DBI) where++import DDF.DBI+import qualified Prelude as M++class DBI r => Bool r where+ bool :: M.Bool -> r h M.Bool+ ite :: r h (a -> a -> M.Bool -> a)
+ DDF/Combine.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE NoImplicitPrelude #-}++module DDF.Combine where++import DDF.Lang+import DDF.ImportMeta++data Combine l r h x = Combine (l h x) (r h x)++instance (DBI l, DBI r) => DBI (Combine l r) where+ z = Combine z z+ s (Combine l r) = Combine (s l) (s r)+ app (Combine fl fr) (Combine xl xr) = Combine (app fl xl) (app fr xr)+ abs (Combine l r) = Combine (abs l) (abs r)+ hoas f = Combine (hoas $ \x -> case f (Combine x z) of Combine l r -> l) (hoas $ \x -> case f (Combine z x) of Combine l r -> r)++instance (Bool l, Bool r) => Bool (Combine l r) where+ bool x = Combine (bool x) (bool x)+ ite = Combine ite ite++instance (Lang l, Lang r) => Lang (Combine l r) where+ mkProd = Combine mkProd mkProd+ zro = Combine zro zro+ fst = Combine fst fst+ double x = Combine (double x) (double x)+ doublePlus = Combine doublePlus doublePlus+ doubleMinus = Combine doubleMinus doubleMinus+ doubleMult = Combine doubleMult doubleMult+ doubleDivide = Combine doubleDivide doubleDivide+ doubleExp = Combine doubleExp doubleExp+ float x = Combine (float x) (float x)+ floatPlus = Combine floatPlus floatPlus+ floatMinus = Combine floatMinus floatMinus+ floatMult = Combine floatMult floatMult+ floatDivide = Combine floatDivide floatDivide+ floatExp = Combine floatExp floatExp+ fix = Combine fix fix+ left = Combine left left+ right = Combine right right+ sumMatch = Combine sumMatch sumMatch+ unit = Combine unit unit+ exfalso = Combine exfalso exfalso+ nothing = Combine nothing nothing+ just = Combine just just+ optionMatch = Combine optionMatch optionMatch+ ioRet = Combine ioRet ioRet+ ioBind = Combine ioBind ioBind+ ioMap = Combine ioMap ioMap+ nil = Combine nil nil+ cons = Combine cons cons+ listMatch = Combine listMatch listMatch+ runWriter = Combine runWriter runWriter+ writer = Combine writer writer+ double2Float = Combine double2Float double2Float+ float2Double = Combine float2Double float2Double+ state = Combine state state+ runState = Combine runState runState
+ DDF/DBI.hs view
@@ -0,0 +1,185 @@+{-# LANGUAGE + MultiParamTypeClasses, + RankNTypes, + ScopedTypeVariables, + FlexibleInstances, + FlexibleContexts, + UndecidableInstances, + PolyKinds, + LambdaCase, + NoMonomorphismRestriction, + TypeFamilies, + LiberalTypeSynonyms, + FunctionalDependencies, + ExistentialQuantification, + InstanceSigs, + ConstraintKinds, + DefaultSignatures, + TypeOperators, + TypeApplications, + PartialTypeSignatures #-} + +module DDF.DBI (module DDF.DBI, module DDF.ImportMeta) where +import qualified Prelude as P +import DDF.Util +import Control.Monad (when) +import System.Random +import Data.Proxy +import Data.Constraint +import Data.Constraint.Forall +import DDF.ImportMeta + +class Monoid r m where + zero :: r h m + plus :: r h (m -> m -> m) + +class Monoid repr w => WithDiff repr w where + withDiff :: repr h ((w -> x) -> w -> Diff x w) + +class DBI repr => ConvDiff repr w where + toDiff :: forall h x. Monoid repr x => Proxy x -> repr h (w -> Diff x w) + toDiff _ = toDiffBy1 @repr @w @x zero + toDiffBy :: forall h x. repr h (x -> w -> Diff x w) + fromDiff :: forall h x. Monoid repr x => Proxy x -> repr h (Diff x w -> w) + fromDiff _ = fromDiffBy1 @repr @w @x zero + fromDiffBy :: repr h (x -> Diff x w -> w) + +withDiff1 = app withDiff +toDiffBy1 :: forall repr w x h. ConvDiff repr w => repr h x -> repr h (w -> Diff x w) +toDiffBy1 = app toDiffBy +fromDiffBy1 :: forall repr w x h. ConvDiff repr w => repr h x -> repr h (Diff x w -> w) +fromDiffBy1 = app fromDiffBy + +selfWithDiff :: (DBI repr, WithDiff repr w) => repr h (w -> Diff w w) +selfWithDiff = withDiff1 id + +class DBI (repr :: * -> * -> *) where + z :: repr (a, h) a + s :: repr h b -> repr (a, h) b + abs :: repr (a, h) b -> repr h (a -> b) + app :: repr h (a -> b) -> repr h a -> repr h b + hoas :: (repr (a, h) a -> repr (a, h) b) -> repr h (a -> b) + hoas f = abs $ f z + com :: repr h ((b -> c) -> (a -> b) -> (a -> c)) + com = lam3 $ \f g x -> app f (app g x) + flip :: repr h ((a -> b -> c) -> (b -> a -> c)) + flip = lam3 $ \f b a -> app2 f a b + id :: repr h (a -> a) + id = lam $ \x -> x + const :: repr h (a -> b -> a) + const = lam2 $ \x _ -> x + scomb :: repr h ((a -> b -> c) -> (a -> b) -> (a -> c)) + scomb = lam3 $ \f x arg -> app2 f arg (app x arg) + dup :: repr h ((a -> a -> b) -> (a -> b)) + dup = lam2 $ \f x -> app2 f x x + let_ :: repr h (a -> (a -> b) -> b) + let_ = flip1 id + +const1 = app const +map2 = app2 map +return = pure +bind2 = app2 bind +map1 = app map +join1 = app join +bimap2 = app2 bimap +bimap3 = app3 bimap +flip1 = app flip +flip2 = app2 flip +let_2 = app2 let_ + +class Functor r f where + map :: r h ((a -> b) -> (f a -> f b)) + +class Functor r a => Applicative r a where + pure :: r h (x -> a x) + ap :: r h (a (x -> y) -> a x -> a y) + +class (DBI r, Applicative r m) => Monad r m where + bind :: r h (m a -> (a -> m b) -> m b) + join :: r h (m (m a) -> m a) + join = lam $ \m -> bind2 m id + bind = lam2 $ \m f -> join1 (app2 map f m) + {-# MINIMAL (join | bind) #-} + +class BiFunctor r p where + bimap :: r h ((a -> b) -> (c -> d) -> p a c -> p b d) + +app3 f x y z = app (app2 f x y) z +com2 = app2 com + +class NT repr l r where + conv :: repr l t -> repr r t + +class NTS repr l r where + convS :: repr l t -> repr r t + +instance (DBI repr, NT repr l r) => NTS repr l (a, r) where + convS = s . conv + +instance {-# OVERLAPPABLE #-} NTS repr l r => NT repr l r where + conv = convS + +instance {-# OVERLAPPING #-} NT repr x x where + conv = P.id + +lam :: forall repr a b h. DBI repr => + ((forall k. NT repr (a, h) k => repr k a) -> (repr (a, h)) b) -> repr h (a -> b) +lam f = hoas (\x -> f $ conv x) + +lam2 :: forall repr a b c h. DBI repr => + ((forall k. NT repr (a, h) k => repr k a) -> (forall k. NT repr (b, (a, h)) k => repr k b) -> (repr (b, (a, h))) c) -> repr h (a -> b -> c) +lam2 f = lam $ \x -> lam $ \y -> f x y + +lam3 f = lam2 $ \x y -> lam $ \z -> f x y z + +type family Diff (v :: *) (x :: *) +type instance Diff v () = () +type instance Diff v (l, r) = (Diff v l, Diff v r) +type instance Diff v (l -> r) = Diff v l -> Diff v r + +newtype WDiff repr v h x = WDiff {runWDiff :: repr (Diff v h) (Diff v x)} + +app2 f a = app (app f a) + +plus2 = app2 plus + +instance DBI repr => DBI (WDiff repr v) where + z = WDiff z + s (WDiff x) = WDiff $ s x + abs (WDiff f) = WDiff $ abs f + app (WDiff f) (WDiff x) = WDiff $ app f x + hoas f = WDiff $ hoas (runWDiff . f . WDiff) + +noEnv :: repr () x -> repr () x +noEnv = P.id + +instance Weight () where weightCon = Sub Dict + +instance Weight P.Double where weightCon = Sub Dict + +instance (Weight l, Weight r) => Weight (l, r) where + weightCon :: forall con. (con (), con P.Float, con P.Double, ForallV (ProdCon con)) :- con (l, r) + weightCon = Sub (mapDict (prodCon \\ (instV :: (ForallV (ProdCon con) :- ProdCon con l r))) (Dict \\ weightCon @l @con \\ weightCon @r @con)) + +class ProdCon con l r where + prodCon :: (con l, con r) :- con (l, r) + +instance ProdCon Random l r where prodCon = Sub Dict + +instance ProdCon RandRange l r where prodCon = Sub Dict + +instance ProdCon P.Show l r where prodCon = Sub Dict + +class Weight w where + weightCon :: (con (), con P.Float, con P.Double, ForallV (ProdCon con)) :- con w + +data RunImpW repr h x = forall w. Weight w => RunImpW (repr h (w -> x)) +data ImpW repr h x = NoImpW (repr h x) | forall w. Weight w => ImpW (repr h (w -> x)) + +type RunImpWR repr h x = forall r. (forall w. Weight w => repr h (w -> x) -> r) -> r + +runImpW2RunImpWR :: RunImpW repr h x -> RunImpWR repr h x +runImpW2RunImpWR (RunImpW x) = \f -> f x + +runImpWR2RunImpW :: RunImpWR repr h x -> RunImpW repr h x +runImpWR2RunImpW f = f RunImpW
+ DDF/Eval.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE NoImplicitPrelude,+ LambdaCase #-}++module DDF.Eval where++import DDF.ImportMeta+import DDF.Lang+import qualified Prelude as M+import qualified Control.Monad.Writer as M+import qualified Control.Monad.State as M+import qualified GHC.Float as M+import qualified Data.Functor.Identity as M+import qualified Data.Bool as M++newtype Eval h x = Eval {runEval :: h -> x}++comb = Eval . M.const++instance DBI Eval where+ z = Eval M.fst+ s (Eval a) = Eval $ a . M.snd+ abs (Eval f) = Eval $ \a h -> f (h, a)+ app (Eval f) (Eval x) = Eval $ \h -> f h $ x h++instance Bool Eval where+ bool = comb+ ite = comb M.bool++instance Lang Eval where+ zro = comb M.fst+ fst = comb M.snd+ mkProd = comb (,)+ double = comb+ doublePlus = comb (+)+ doubleMinus = comb (-)+ doubleMult = comb (*)+ doubleDivide = comb (/)+ fix = comb loop+ where loop x = x $ loop x+ left = comb M.Left+ right = comb M.Right+ sumMatch = comb $ \l r -> \case+ M.Left x -> l x+ M.Right x -> r x+ unit = comb ()+ exfalso = comb absurd+ nothing = comb M.Nothing+ just = comb M.Just+ ioRet = comb M.return+ ioBind = comb (>>=)+ nil = comb []+ cons = comb (:)+ listMatch = comb $ \l r -> \case+ [] -> l+ x:xs -> r x xs+ optionMatch = comb $ \l r -> \case+ M.Nothing -> l+ M.Just x -> r x+ ioMap = comb M.fmap+ writer = comb (M.WriterT . M.Identity)+ runWriter = comb M.runWriter+ doubleExp = comb M.exp+ float = comb+ floatPlus = comb (+)+ floatMinus = comb (-)+ floatMult = comb (*)+ floatDivide = comb (/)+ floatExp = comb M.exp+ float2Double = comb M.float2Double+ double2Float = comb M.double2Float+ state = comb M.state+ runState = comb M.runState
+ DDF/GWDiff.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE NoImplicitPrelude, RankNTypes #-}++module DDF.GWDiff where+import DDF.Lang+import qualified Prelude as M+import Data.Proxy++newtype GWDiff repr h x = GWDiff {runGWDiff :: forall v. Vector repr v => Proxy v -> repr (Diff v h) (Diff v x)}++instance DBI repr => DBI (GWDiff repr) where+ z = GWDiff (M.const z)+ s (GWDiff x) = GWDiff (\p -> s $ x p)+ app (GWDiff f) (GWDiff x) = GWDiff (\p -> app (f p) (x p))+ abs (GWDiff x) = GWDiff (\p -> abs $ x p)++instance Bool r => Bool (GWDiff r) where+ bool x = GWDiff $ M.const $ bool x+ ite = GWDiff $ M.const ite++instance Lang repr => Lang (GWDiff repr) where+ mkProd = GWDiff (M.const mkProd)+ zro = GWDiff $ M.const zro+ fst = GWDiff $ M.const fst+ double x = GWDiff $ M.const $ mkProd2 (double x) zero+ doublePlus = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))+ doubleMinus = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))+ doubleMult = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (mult2 (zro1 l) (zro1 r))+ (plus2 (mult2 (zro1 l) (fst1 r)) (mult2 (zro1 r) (fst1 l)))+ doubleDivide = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (divide2 (zro1 l) (zro1 r))+ (divide2 (minus2 (mult2 (zro1 r) (fst1 l)) (mult2 (zro1 l) (fst1 r)))+ (mult2 (zro1 r) (zro1 r)))+ doubleExp = GWDiff $ M.const $ lam $ \x -> mkProd2 (doubleExp1 (zro1 x)) (mult2 (doubleExp1 (zro1 x)) (fst1 x))+ fix = GWDiff $ M.const fix+ left = GWDiff $ M.const left+ right = GWDiff $ M.const right+ sumMatch = GWDiff $ M.const sumMatch+ unit = GWDiff $ M.const unit+ exfalso = GWDiff $ M.const exfalso+ nothing = GWDiff $ M.const nothing+ just = GWDiff $ M.const just+ ioRet = GWDiff $ M.const ioRet+ ioBind = GWDiff $ M.const ioBind+ nil = GWDiff $ M.const nil+ cons = GWDiff $ M.const cons+ listMatch = GWDiff $ M.const listMatch+ optionMatch = GWDiff $ M.const optionMatch+ ioMap = GWDiff $ M.const ioMap+ writer = GWDiff $ M.const writer+ runWriter = GWDiff $ M.const runWriter+ float x = GWDiff $ M.const $ mkProd2 (float x) zero+ floatPlus = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))+ floatMinus = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))+ floatMult = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (mult2 (float2Double1 (zro1 l)) (zro1 r))+ (plus2 (mult2 (float2Double1 (zro1 l)) (fst1 r)) (mult2 (float2Double1 (zro1 r)) (fst1 l)))+ floatDivide = GWDiff $ M.const $ lam2 $ \l r ->+ mkProd2 (divide2 (zro1 l) (float2Double1 (zro1 r)))+ (divide2 (minus2 (mult2 (float2Double1 (zro1 r)) (fst1 l)) (mult2 (float2Double1 (zro1 l)) (fst1 r)))+ (float2Double1 (mult2 (float2Double1 (zro1 r)) (zro1 r))))+ floatExp = GWDiff $ M.const $ lam $ \x -> mkProd2 (floatExp1 (zro1 x)) (mult2 (float2Double1 (floatExp1 (zro1 x))) (fst1 x))+ float2Double = GWDiff $ M.const $ bimap2 float2Double id+ double2Float = GWDiff $ M.const $ bimap2 double2Float id+ state = GWDiff $ M.const state+ runState = GWDiff $ M.const runState
+ DDF/ImportMeta.hs view
@@ -0,0 +1,6 @@+{-# LANGUAGE NoImplicitPrelude #-}++module DDF.ImportMeta (module Prelude, module Data.Void) where++import Prelude (($), show, (+), (-), (*), (/), (.), (++), (>>=), Double, IO, Int, (<=), print)+import Data.Void (absurd)
+ DDF/Lang.hs view
@@ -0,0 +1,442 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ RankNTypes,+ ScopedTypeVariables,+ FlexibleInstances,+ FlexibleContexts,+ UndecidableInstances,+ PolyKinds,+ LambdaCase,+ NoMonomorphismRestriction,+ TypeFamilies,+ LiberalTypeSynonyms,+ FunctionalDependencies,+ ExistentialQuantification,+ InstanceSigs,+ TupleSections,+ ConstraintKinds,+ DefaultSignatures,+ TypeOperators,+ TypeApplications,+ PartialTypeSignatures #-}++module DDF.Lang (module DDF.Lang, module DDF.Bool) where+import DDF.DBI+import qualified Prelude as P+import Prelude (($), (.), (+), (-), (++), show, (>>=), (*), (/), Double, Either, IO, Maybe)+import qualified Control.Monad.Writer as P+import Control.Monad.Writer (Writer, WriterT)+import qualified Control.Monad.State as P+import Control.Monad.State (State)+import qualified GHC.Float as P+import GHC.Float (Float)+import qualified Data.Tuple as P+import Data.Void+import Data.Proxy+import Data.Proxy+import Data.Constraint+import Data.Constraint.Forall+import qualified Data.Bool as P+import DDF.Bool++type instance Diff v Void = Void+type instance Diff v P.Double = (P.Double, v)+type instance Diff v P.Float = (P.Float, v)+type instance Diff v (Writer l r) = Writer (Diff v l) (Diff v r)+type instance Diff v (IO l) = IO (Diff v l)+type instance Diff v (Maybe l) = Maybe (Diff v l)+type instance Diff v [l] = [Diff v l]+type instance Diff v (Either l r) = Either (Diff v l) (Diff v r)+type instance Diff v (State l r) = State (Diff v l) (Diff v r)+type instance Diff v P.Bool = P.Bool++class Bool repr => Lang repr where+ mkProd :: repr h (a -> b -> (a, b))+ zro :: repr h ((a, b) -> a)+ fst :: repr h ((a, b) -> b)+ double :: P.Double -> repr h P.Double+ doubleZero :: repr h P.Double+ doubleZero = double 0+ doubleOne :: repr h P.Double+ doubleOne = double 1+ doublePlus :: repr h (P.Double -> P.Double -> P.Double)+ doubleMinus :: repr h (P.Double -> P.Double -> P.Double)+ doubleMult :: repr h (P.Double -> P.Double -> P.Double)+ doubleDivide :: repr h (P.Double -> P.Double -> P.Double)+ doubleExp :: repr h (P.Double -> P.Double)+ float :: P.Float -> repr h P.Float+ floatZero :: repr h P.Float+ floatZero = float 0+ floatOne :: repr h P.Float+ floatOne = float 1+ floatPlus :: repr h (P.Float -> P.Float -> P.Float)+ floatMinus :: repr h (P.Float -> P.Float -> P.Float)+ floatMult :: repr h (P.Float -> P.Float -> P.Float)+ floatDivide :: repr h (P.Float -> P.Float -> P.Float)+ floatExp :: repr h (P.Float -> P.Float)+ fix :: repr h ((a -> a) -> a)+ left :: repr h (a -> P.Either a b)+ right :: repr h (b -> P.Either a b)+ sumMatch :: repr h ((a -> c) -> (b -> c) -> P.Either a b -> c)+ unit :: repr h ()+ exfalso :: repr h (Void -> a)+ nothing :: repr h (P.Maybe a)+ just :: repr h (a -> P.Maybe a)+ optionMatch :: repr h (b -> (a -> b) -> P.Maybe a -> b)+ ioRet :: repr h (a -> P.IO a)+ ioBind :: repr h (P.IO a -> (a -> P.IO b) -> P.IO b)+ ioMap :: repr h ((a -> b) -> P.IO a -> P.IO b)+ nil :: repr h [a]+ cons :: repr h (a -> [a] -> [a])+ listMatch :: repr h (b -> (a -> [a] -> b) -> [a] -> b)+ listAppend :: repr h ([a] -> [a] -> [a])+ listAppend = lam2 $ \l r -> fix2 (lam $ \self -> listMatch2 r (lam2 $ \a as -> cons2 a (app self as))) l+ writer :: repr h ((a, w) -> P.Writer w a)+ runWriter :: repr h (P.Writer w a -> (a, w))+ swap :: repr h ((l, r) -> (r, l))+ swap = lam $ \p -> mkProd2 (fst1 p) (zro1 p)+ curry :: repr h (((a, b) -> c) -> (a -> b -> c))+ uncurry :: repr h ((a -> b -> c) -> ((a, b) -> c))+ curry = lam3 $ \f a b -> app f (mkProd2 a b)+ uncurry = lam2 $ \f p -> app2 f (zro1 p) (fst1 p)+ float2Double :: repr h (P.Float -> P.Double)+ double2Float :: repr h (P.Double -> P.Float)+ undefined :: repr h a+ undefined = fix1 id+ state :: repr h ((l -> (r, l)) -> State l r)+ runState :: repr h (State l r -> (l -> (r, l)))++instance Lang repr => ConvDiff repr () where+ toDiffBy = const1 id+ fromDiffBy = const1 id++instance Lang repr => ConvDiff repr Double where+ toDiffBy = flip1 mkProd+ fromDiffBy = const1 zro++instance Lang repr => ConvDiff repr Float where+ toDiffBy = flip1 mkProd+ fromDiffBy = const1 zro++instance (Lang repr, ConvDiff repr l, ConvDiff repr r) => ConvDiff repr (l, r) where+ toDiffBy = lam $ \x -> bimap2 (toDiffBy1 x) (toDiffBy1 x)+ fromDiffBy = lam $ \x -> bimap2 (fromDiffBy1 x) (fromDiffBy1 x)++instance (Lang repr, ConvDiff repr l, ConvDiff repr r) => ConvDiff repr (Either l r) where+ toDiffBy = lam $ \x -> bimap2 (toDiffBy1 x) (toDiffBy1 x)+ fromDiffBy = lam $ \x -> bimap2 (fromDiffBy1 x) (fromDiffBy1 x)++instance (Lang repr, ConvDiff repr l, ConvDiff repr r) => ConvDiff repr (l -> r) where+ toDiffBy = lam2 $ \x f -> (toDiffBy1 x) `com2` f `com2` (fromDiffBy1 x)+ fromDiffBy = lam2 $ \x f -> (fromDiffBy1 x) `com2` f `com2` (toDiffBy1 x)++instance (Lang repr, ConvDiff repr l) => ConvDiff repr [l] where+ toDiffBy = lam $ \x -> map1 (toDiffBy1 x)+ fromDiffBy = lam $ \x -> map1 (fromDiffBy1 x)++class Reify repr x where+ reify :: x -> repr h x++instance Lang repr => Reify repr () where+ reify _ = unit++instance Lang repr => Reify repr 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 (Bool r, Vector r v) => Bool (WDiff r v) where+ bool = WDiff . bool+ ite = WDiff ite++instance (Vector repr v, Lang repr) => Lang (WDiff repr v) where+ mkProd = WDiff mkProd+ zro = WDiff zro+ fst = WDiff fst+ double x = WDiff $ mkProd2 (double x) zero+ doublePlus = WDiff $ lam2 $ \l r ->+ mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))+ doubleMinus = WDiff $ lam2 $ \l r ->+ mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))+ doubleMult = WDiff $ lam2 $ \l r ->+ mkProd2 (mult2 (zro1 l) (zro1 r))+ (plus2 (mult2 (zro1 l) (fst1 r)) (mult2 (zro1 r) (fst1 l)))+ doubleDivide = WDiff $ lam2 $ \l r ->+ mkProd2 (divide2 (zro1 l) (zro1 r))+ (divide2 (minus2 (mult2 (zro1 r) (fst1 l)) (mult2 (zro1 l) (fst1 r)))+ (mult2 (zro1 r) (zro1 r)))+ doubleExp = WDiff $ lam $ \x -> mkProd2 (doubleExp1 (zro1 x)) (mult2 (doubleExp1 (zro1 x)) (fst1 x))+ fix = WDiff fix+ left = WDiff left+ right = WDiff right+ sumMatch = WDiff sumMatch+ unit = WDiff unit+ exfalso = WDiff exfalso+ nothing = WDiff nothing+ just = WDiff just+ ioRet = WDiff ioRet+ ioBind = WDiff ioBind+ nil = WDiff nil+ cons = WDiff cons+ listMatch = WDiff listMatch+ optionMatch = WDiff optionMatch+ ioMap = WDiff ioMap+ writer = WDiff writer+ runWriter = WDiff runWriter+ float x = WDiff $ mkProd2 (float x) zero+ floatPlus = WDiff $ lam2 $ \l r ->+ mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))+ floatMinus = WDiff $ lam2 $ \l r ->+ mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))+ floatMult = WDiff $ lam2 $ \l r ->+ mkProd2 (mult2 (float2Double1 (zro1 l)) (zro1 r))+ (plus2 (mult2 (float2Double1 (zro1 l)) (fst1 r)) (mult2 (float2Double1 (zro1 r)) (fst1 l)))+ floatDivide = WDiff $ lam2 $ \l r ->+ mkProd2 (divide2 (zro1 l) (float2Double1 (zro1 r)))+ (divide2 (minus2 (mult2 (float2Double1 (zro1 r)) (fst1 l)) (mult2 (float2Double1 (zro1 l)) (fst1 r)))+ (float2Double1 (mult2 (float2Double1 (zro1 r)) (zro1 r))))+ floatExp = WDiff $ lam $ \x -> mkProd2 (floatExp1 (zro1 x)) (mult2 (float2Double1 (floatExp1 (zro1 x))) (fst1 x))+ float2Double = WDiff $ bimap2 float2Double id+ double2Float = WDiff $ bimap2 double2Float id+ state = WDiff state+ runState = WDiff runState++instance Lang repr => ProdCon (Monoid repr) l r where prodCon = Sub Dict++instance Lang repr => ProdCon (WithDiff 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++instance Lang repr => Lang (ImpW repr) where+ nil = NoImpW nil+ cons = NoImpW cons+ listMatch = NoImpW listMatch+ zro = NoImpW zro+ fst = NoImpW fst+ mkProd = NoImpW mkProd+ ioRet = NoImpW ioRet+ ioMap = NoImpW ioMap+ ioBind = NoImpW ioBind+ unit = NoImpW unit+ nothing = NoImpW nothing+ just = NoImpW just+ optionMatch = NoImpW optionMatch+ exfalso = NoImpW exfalso+ fix = NoImpW fix+ left = NoImpW left+ right = NoImpW right+ sumMatch = NoImpW sumMatch+ writer = NoImpW writer+ runWriter = NoImpW runWriter+ double = NoImpW . double+ doubleExp = NoImpW doubleExp+ doublePlus = NoImpW doublePlus+ doubleMinus = NoImpW doubleMinus+ doubleMult = NoImpW doubleMult+ doubleDivide = NoImpW doubleDivide+ float = NoImpW . float+ floatExp = NoImpW floatExp+ floatPlus = NoImpW floatPlus+ floatMinus = NoImpW floatMinus+ floatMult = NoImpW floatMult+ floatDivide = NoImpW floatDivide+ float2Double = NoImpW float2Double+ double2Float = NoImpW double2Float+ state = NoImpW state+ runState = NoImpW runState++instance Lang r => Bool (ImpW r) where+ bool = NoImpW . bool+ ite = NoImpW ite++instance Lang repr => WithDiff repr () where+ withDiff = const1 id++instance Lang repr => WithDiff repr Double where+ withDiff = lam2 $ \conv d -> mkProd2 d (app conv doubleOne)++instance Lang repr => WithDiff repr P.Float where+ withDiff = lam2 $ \conv d -> mkProd2 d (app conv floatOne)++instance (Lang repr, WithDiff repr l, WithDiff repr r) => WithDiff repr (l, r) where+ withDiff = lam $ \conv -> bimap2 (withDiff1 (lam $ \l -> app conv (mkProd2 l zero))) (withDiff1 (lam $ \r -> app conv (mkProd2 zero r)))++class Monoid r g => Group r g where+ invert :: r h (g -> g)+ minus :: r h (g -> g -> g)+ default invert :: Lang r => r h (g -> g)+ invert = minus1 zero+ default minus :: Lang r => r h (g -> g -> g)+ minus = lam2 $ \x y -> plus2 x (invert1 y)+ {-# MINIMAL (invert | minus) #-}++class Group r v => Vector r v where+ mult :: r h (Double -> v -> v)+ divide :: r h (v -> Double -> v)+ default mult :: Lang r => r h (Double -> v -> v)+ mult = lam2 $ \x y -> divide2 y (recip1 x)+ default divide :: Lang r => r h (v -> Double -> v)+ divide = lam2 $ \x y -> mult2 (recip1 y) x+ {-# MINIMAL (mult | divide) #-}++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 Lang r => Monoid r Double where+ zero = doubleZero+ plus = doublePlus++instance Lang r => Group r Double where+ minus = doubleMinus++instance Lang r => Vector r Double where+ mult = doubleMult+ divide = doubleDivide++instance Lang r => Monoid r P.Float where+ zero = floatZero+ plus = floatPlus++instance Lang r => Group r P.Float where+ minus = floatMinus++instance Lang r => Vector r P.Float where+ mult = com2 floatMult double2Float+ divide = com2 (flip2 com double2Float) floatDivide++instance (Lang 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 (Lang repr, Group repr l, Group repr r) => Group repr (l, r) where+ invert = bimap2 invert invert++instance (Lang repr, Vector repr l, Vector repr r) => Vector repr (l, r) where+ mult = lam $ \x -> bimap2 (mult1 x) (mult1 x)++instance (Lang repr, Monoid repr v) => Monoid repr (Double -> v) where+ zero = const1 zero+ plus = lam3 $ \l r x -> plus2 (app l x) (app r x)++instance (Lang repr, Group repr v) => Group repr (Double -> v) where+ invert = lam2 $ \l x -> app l (invert1 x)++instance (Lang repr, Vector repr v) => Vector repr (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 Lang r => BiFunctor r (,) where+ bimap = lam3 $ \l r p -> mkProd2 (app l (zro1 p)) (app r (fst1 p))++instance Lang r => Functor r (Writer w) where+ map = lam $ \f -> com2 writer (com2 (bimap2 f id) runWriter)++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 s -> state1 (com2 (bimap2 f id) (runState1 s))++instance Lang r => Applicative r (State l) where+ pure = lam $ \x -> state1 (mkProd1 x)+ ap = lam2 $ \f x -> state1 $ lam $ \s -> let_2 (runState2 f s) (lam $ \p -> bimap3 (zro1 p) id (runState2 x (fst1 p)))++instance Lang r => Monad r (State l) where+ join = lam $ \x -> state1 $ lam $ \s -> let_2 (runState2 x s) (uncurry1 runState)++instance Lang r => Functor r P.IO where+ map = ioMap++instance Lang r => Applicative r P.IO where+ pure = ioRet+ ap = lam2 $ \f x -> ioBind2 f (flip2 ioMap x)++instance Lang r => Monad r P.IO where+ bind = ioBind++instance Lang r => Functor r P.Maybe where+ map = lam $ \func -> optionMatch2 nothing (com2 just func)++instance Lang r => Applicative r P.Maybe where+ pure = just+ ap = optionMatch2 (const1 nothing) map++instance Lang r => Monad r P.Maybe where+ bind = lam2 $ \x func -> optionMatch3 nothing func x++runImpW :: forall repr h x. Lang repr => ImpW repr h x -> RunImpW repr h x+runImpW (ImpW x) = RunImpW x+runImpW (NoImpW x) = RunImpW (const1 x :: repr h (() -> x))++instance Lang repr => DBI (ImpW repr) where+ z = NoImpW z+ s :: forall a h b. ImpW repr h b -> ImpW repr (a, h) b+ s (ImpW x) = work x+ where+ work :: Weight w => repr h (w -> b) -> ImpW repr (a, h) b+ work x = ImpW (s x)+ s (NoImpW x) = NoImpW (s x)+ app (ImpW f) (ImpW x) = ImpW (lam $ \p -> app (app (conv f) (zro1 p)) (app (conv x) (fst1 p)))+ app (NoImpW f) (NoImpW x) = NoImpW (app f x)+ app (ImpW f) (NoImpW x) = ImpW (lam $ \w -> app2 (conv f) w (conv x))+ app (NoImpW f) (ImpW x) = ImpW (lam $ \w -> app (conv f) (app (conv x) w))+ abs (ImpW f) = ImpW (flip1 $ abs f)+ abs (NoImpW x) = NoImpW (abs x)++++cons2 = app2 cons+listMatch2 = app2 listMatch+fix1 = app fix+fix2 = app2 fix+uncurry1 = app uncurry+optionMatch2 = app2 optionMatch+optionMatch3 = app3 optionMatch+zro1 = app zro+fst1 = app fst+mult1 = app mult+mult2 = app2 mult+divide2 = app2 divide+invert1 = app invert+mkProd1 = app mkProd+mkProd2 = app2 mkProd+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
+ DDF/Poly.lhs view
@@ -0,0 +1,108 @@+> {-# LANGUAGE +> MultiParamTypeClasses, +> RankNTypes, +> ScopedTypeVariables, +> FlexibleInstances, +> FlexibleContexts, +> UndecidableInstances, +> IncoherentInstances, +> PolyKinds, +> LambdaCase, +> NoMonomorphismRestriction, +> TypeFamilies, +> LiberalTypeSynonyms, +> EmptyCase #-} + +> module DDF.Poly where +> import Control.Monad (when) +> import DDF.Util +> import DDF.Lang +> import DDF.Show +> import DDF.Eval +> import qualified Control.Monad as M + +Importing files and opening language extension... +So, our goal is to find x, where x * x + 2 * x + 3 = 27. +To do so, we try to minimize their difference squared (l2 norm). + +> poly :: forall repr h. Lang repr => repr h (Double -> Double) +> poly = lam $ \x -> plus2 (mult2 x x) (plus2 (mult2 (double 2.0) x) (double 3.0)) + +poly x = x * x + (2 * x + 3) + +> l2 = lam $ \x -> mult2 (minus2 x (double 27)) (minus2 x (double 27)) + +l2 x = (x - 27) * (x - 27) +l2 measure how far is the input from 27 + +> comp = com2 l2 poly + +By composing the two, we can measure how far is x * x + 2 * x + 3 from 27. +We want to minimize this distance. + +Now write a generic function that calculate x and return it. + +> solve :: forall m. M.Monad m => (AST -> m ()) -> (Integer -> Double -> m ()) -> m Double +> solve doAST doIter = do + +Let's begin by trying to print poly + +> doAST $ runShow poly vars 0 +> go 0 0 +> where + +The main loop. i is step and w is weight (our current estimate of x). +We start by assuming x = 0 is the solution, +and minimize (comp x) by taking derivative of x, and decrease it whenever it is positive (and vice versa). + +> go :: Integer -> Double -> m Double +> go i w | i < 200 = do +> doIter i w +> go (1 + i) $ w - 0.001 * snd (runEval (runWDiff $ noEnv comp) () (w, 1)) + +noEnv comp assume the term (which is a De Brujin Index term) need no environment (is free) +and it is a finally tagless term, with WDiff interpreter being implicitly applied, +which return another finally tagless term, but taking derivative of x. +it is then applied to Eval interpreter (which eval it in the meta language, haskell). +similar to runWDiff, we use runEval to take out the term from a newtype +now we apply the environment (remember it has no environment? so just stick a unit) +and a pair, the zeroth being x, the first being derivative of x, which is 1. +the whole computation return a pair of (x * x + (2 * x + 3) - 27)^2, and it's derivative. +we modify w using the derivative. + +> go i w = M.return w + +By running the program, you shall see +(\a -> (plus (mult a a) (plus (mult 2.0 a) 3.0))) +since we pretty print poly +followed by something like +0.0 +9.6e-2 +0.43573084645674215 +1.1890033104995505 +2.498644212525056 +3.652210805402036 +3.9662181049468925 +3.9981203814732154 +3.9999338218043157 +3.999998509763363 +3.9999999785234146 +3.9999999998019136 +3.9999999999988307 +3.9999999999999956 +3.999999999999999 +which mean we found 4 as a soultion. +plugging it back to the equation, we can verify that (4 * 4) + 2 * 4 + 3 is indeed 27! + +Now the main function: + +> main :: IO () +> main = do +> d <- solve print printSquare +> putStrLn $ "x is: " ++ (show d) +> M.return () +> where +> printSquare i x = when (isSquare i) (print x) + +the only thing worth noting is that we print the weight in increasing interval, +so initially more weight is printed
+ DDF/Show.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE NoImplicitPrelude #-}++module DDF.Show (module DDF.Show) where++import DDF.Lang+import qualified Prelude as M+import DDF.ImportMeta++data AST = Leaf M.String | App M.String AST [AST] | Lam M.String [M.String] AST++appAST (Leaf f) x = App f x []+appAST (App f x l) r = App f x (l ++ [r])+appAST lam r = appAST (Leaf $ show lam) r++lamAST str (Lam s l t) = Lam str (s:l) t+lamAST str r = Lam str [] r++instance M.Show AST where+ show (Leaf f) = f+ show (App f x l) = "(" ++ f ++ " " ++ show x ++ M.concatMap ((" " ++) . show) l ++ ")"+ show (Lam s l t) = "(\\" ++ s ++ M.concatMap (" " ++) l ++ " -> " ++ show t ++ ")"++newtype Show h a = Show {runShow :: [M.String] -> M.Int -> AST}+name = Show . M.const . M.const . Leaf++instance DBI Show where+ z = Show $ M.const $ Leaf . show . M.flip (-) 1+ s (Show v) = Show $ \vars -> v vars . M.flip (-) 1+ abs (Show f) = Show $ \vars x -> lamAST (show x) (f vars (x + 1))+ app (Show f) (Show x) = Show $ \vars h -> appAST (f vars h) (x vars h)+ hoas f = Show $ \(v:vars) h ->+ lamAST v (runShow (f $ Show $ M.const $ M.const $ Leaf v) vars (h + 1))++instance Bool Show where+ bool = name . show+ ite = name "ite"++instance Lang Show where+ mkProd = name "mkProd"+ zro = name "zro"+ fst = name "fst"+ double = name . show+ doublePlus = name "plus"+ doubleMinus = name "minus"+ doubleMult = name "mult"+ doubleDivide = name "divide"+ doubleExp = name "exp"+ fix = name "fix"+ left = name "left"+ right = name "right"+ sumMatch = name "sumMatch"+ unit = name "unit"+ exfalso = name "exfalso"+ nothing = name "nothing"+ just = name "just"+ ioRet = name "ioRet"+ ioBind = name "ioBind"+ nil = name "nil"+ cons = name "cons"+ listMatch = name "listMatch"+ optionMatch = name "optionMatch"+ ioMap = name "ioMap"+ writer = name "writer"+ runWriter = name "runWriter"+ float = name . show+ floatPlus = name "plus"+ floatMinus = name "minus"+ floatMult = name "mult"+ floatDivide = name "divide"+ floatExp = name "exp"+ float2Double = name "float2Double"+ double2Float = name "double2Float"+ state = name "state"+ runState = name "runState"
+ DDF/UnHOAS.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE NoImplicitPrelude #-}++module DDF.UnHOAS where++import DDF.Lang++newtype UnHOAS repr h x = UnHOAS {runUnHOAS :: repr h x}++instance DBI repr => DBI (UnHOAS repr) where+ z = UnHOAS z+ s (UnHOAS x) = UnHOAS $ s x+ abs (UnHOAS x) = UnHOAS $ abs x+ app (UnHOAS f) (UnHOAS x) = UnHOAS $ app f x++instance Bool r => Bool (UnHOAS r) where+ bool = UnHOAS . bool+ ite = UnHOAS ite++instance Lang repr => Lang (UnHOAS repr) where+ mkProd = UnHOAS mkProd+ zro = UnHOAS zro+ fst = UnHOAS fst+ double = UnHOAS . double+ doublePlus = UnHOAS doublePlus+ doubleMinus = UnHOAS doubleMinus+ doubleMult = UnHOAS doubleMult+ doubleDivide = UnHOAS doubleDivide+ doubleExp = UnHOAS doubleExp+ fix = UnHOAS fix+ left = UnHOAS left+ right = UnHOAS right+ sumMatch = UnHOAS sumMatch+ unit = UnHOAS unit+ exfalso = UnHOAS exfalso+ nothing = UnHOAS nothing+ just = UnHOAS just+ ioRet = UnHOAS ioRet+ ioBind = UnHOAS ioBind+ nil = UnHOAS nil+ cons = UnHOAS cons+ listMatch = UnHOAS listMatch+ optionMatch = UnHOAS optionMatch+ ioMap = UnHOAS ioMap+ writer = UnHOAS writer+ runWriter = UnHOAS runWriter+ float = UnHOAS . float+ floatPlus = UnHOAS floatPlus+ floatMinus = UnHOAS floatMinus+ floatMult = UnHOAS floatMult+ floatDivide = UnHOAS floatDivide+ floatExp = UnHOAS floatExp+ float2Double = UnHOAS float2Double+ double2Float = UnHOAS double2Float+ state = UnHOAS state+ runState = UnHOAS runState
+ DDF/Util.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE TupleSections #-} + +module DDF.Util where + +import System.Random +import GHC.Float + +vars = [pre : suf | suf <- "":map show [0..], pre <- ['a'..'z']] + +isSquare n = sq * sq == n + where sq = floor $ sqrt (fromIntegral n::Double) + +instance Random () where + random = ((),) + randomR _ = random + +instance (Random l, Random r) => Random (l, r) where + random g0 = ((l, r), g2) + where + (l, g1) = random g0 + (r, g2) = random g1 + randomR ((llo, rlo), (lhi, rhi)) g0 = ((l, r), g2) + where + (l, g1) = randomR (llo, lhi) g0 + (r, g2) = randomR (rlo, rhi) g1 + +class RandRange w where + randRange :: (Double, Double) -> (w, w) + +instance RandRange () where + randRange _ = ((), ()) + +instance RandRange Double where + randRange (lo, hi) = (lo, hi) + +instance RandRange Float where + randRange (lo, hi) = (double2Float lo, double2Float hi) + +instance (RandRange l, RandRange r) => RandRange (l, r) where + randRange (lo, hi) = ((llo, rlo), (lhi, rhi)) + where + (llo, lhi) = randRange (lo, hi) + (rlo, rhi) = randRange (lo, hi)
+ DDF/Xor.lhs view
@@ -0,0 +1,129 @@+> {-# LANGUAGE ScopedTypeVariables, NoMonomorphismRestriction, TypeApplications, RankNTypes #-}++This is the classical example of using sigmoid NN to approximate Xor.++> module DDF.Xor where+> import qualified DDF.Poly as YouShouldAlreadyReadThis+> import qualified Prelude as M+> import System.Random+> import Control.Monad (when)+> import Data.Proxy+> import Data.Constraint+> import DDF.Util+> import DDF.Lang+> import DDF.Show+> import DDF.Combine+> import DDF.Eval+> import DDF.GWDiff++Recall in poly, we constructed a function Double -> Double,+with argument being the weight, and do gradient descend to found a solution.++However, most of the time, there wil be more than one weight (or no weight at all).+Also, when we are composing a Neural Network to approximate a value, we dont really care how much weight it use.+So, we use existential type to hide the actual weight.++data ImpW repr h x = forall w. Weight w => ImpW (repr h (w -> x))++ImpW stands for implicit weights.+The existential w is weight, and a Neural Network of type x is just a function from w to x!+We require that the weight can be constructed randomly, so we have random initialization.+Weight also form a Vector so we can combine weights (update it), scale it (to control the learning rate).++Let's start by constructing a weight.++> weight :: Lang repr => ImpW repr h Double+> weight = ImpW id++Note that we are just manipulating AST.+If you wanna do weight sharing, you need to use let(in DDF) yourself.++Obviously, we just need to take the implicit argument.++We have the weight, now we need the activation function, sigmoid.++> sigmoid = lam $ \x -> recip1 (plus2 doubleOne (doubleExp1 (invert1 x)))+> sigmoid1 = app sigmoid++With weight and sigmoid we can construct a neuron of type ((Double, Double) -> Double)+The weight should be a pair of Double, each as a scale on the actual input, with a bias.+We then add the two scaled input, with the bias, and pass them into sigmoid.++> scaleAdd :: Lang repr => ImpW repr h ((Double, Double) -> Double)+> scaleAdd = ImpW $ lam2 $ \w p -> plus2 (mult2 (zro1 w) (zro1 p)) (plus2 (fst1 w) (fst1 p))++> withBias :: Lang repr => ImpW repr h (Double -> Double)+> withBias = ImpW $ plus++> neuron :: Lang repr => ImpW repr h ((Double, Double) -> Double)+> neuron = com2 (com2 sigmoid withBias) scaleAdd+> neuron1 = app neuron++Now, the hidden layer of type (Double, Double) -> ((Double, Double), (Double, Double))++> hidden = lam $ \p -> mkProd2 (mkProd2 (neuron1 p) (neuron1 p)) (mkProd2 (neuron1 p) (neuron1 p))++And finally, the whole NN:++> type XOR = (Double, Double) -> Double+> xor :: Lang repr => ImpW repr h XOR+> xor = neuron `com2` (bimap2 scaleAdd scaleAdd) `com2` hidden++But before we can train it, we need to define the dataset and the loss function.++> l2 :: Lang repr => repr h (Double -> Double -> Double)+> l2 = lam2 $ \l r -> (mult2 (minus2 l r) (minus2 l r))+> l22 = app2 l2++> eval :: Lang repr => repr h (XOR -> ((Double, Double), Double) -> Double)+> eval = lam2 $ \xor p -> l22 (app xor (zro1 p)) (fst1 p)++> dataset :: Lang repr => repr h [((Double, Double), Double)]+> dataset = cons2 (build 0 0 0) (cons2 (build 0 1 1) (cons2 (build 1 0 1) (cons2 (build 1 1 0) nil)))+> where build l r ret = mkProd2 (mkProd2 (double l) (double r)) (double ret)++However, unlike Poly, there are more than one datapoint, so we need to use a list, and map xor onto it.++> loss :: Lang repr => repr h (XOR -> Double)+> loss = lam $ \xor -> fix2 (lam $ \self -> listMatch2 doubleZero (lam2 $ \x xs -> plus2 x (app self xs))) (map2 (app eval xor) dataset)++Now we are good to implement the train function!++> findXor :: forall g m. (RandomGen g, M.Monad m) => g -> (AST -> m ()) -> (Int -> Double -> M.String -> m ()) -> m XOR+> findXor rand doAST doIter = case runImpW $ noEnv xor of+> RunImpW ((Combine (Show xorS) (Combine (Eval xorEv) xorE)) :: Weight w => Combine Show (Combine Eval (GWDiff Eval)) () (w -> XOR)) -> do+> doAST $ xorS vars 0++printing weights. now you will see a list of gibberish++> let initWeight :: w = M.fst $ ((randomR (randRange (-0.01, 0.01)) \\ weightCon @w @Random) \\ weightCon @w @RandRange) rand++Getting random weights...++> (go (diff xorE) initWeight (runEval selfWithDiff () \\ weightCon @w @(WithDiff Eval)) (diff loss)+> ((runEval (lam3 $ \d o n -> minus2 o (mult2 d n)) ()) \\ weightCon @w @(Vector Eval)) 0 (xorEv ())) \\ weightCon @w @M.Show+> where+> diff :: GWDiff Eval () x -> Diff w x+> diff x = (runEval (runGWDiff x (Proxy :: Proxy w)) ()) \\ weightCon @w @(Vector Eval)+> go :: M.Show w => (Diff w (w -> XOR)) -> w -> (w -> Diff w w) -> (Diff w (XOR -> Double)) -> (Double -> w -> w -> w) -> Int -> (w -> XOR) -> m XOR+> go xor weight reify loss update i orig | i <= 2500 = do+> doIter i lossVal (M.show weight)+> go xor (update 0.3 weight lossDiff) reify loss update (1 + i) orig+> where+> (lossVal, lossDiff) = loss $ xor (reify weight)+> go xor weight _ _ _ _ orig = M.return $ orig weight++> main :: IO ()+> main = do+> g <- getStdGen+> xor <- findXor g print (\i d w -> when (isSquare i) $ do+> print d+> M.putStrLn w+> M.putStrLn "")+> let doXor :: Double -> Double -> IO ()+> doXor l r = M.putStrLn $ M.show l ++ " xor " ++ M.show r ++ " is " ++ (M.show $ xor (l, r))+> doXor 0 0+> doXor 0 1+> doXor 1 0+> doXor 1 1+> M.return ()
DeepDarkFantasy.cabal view
@@ -1,5 +1,5 @@ name: DeepDarkFantasy-version: 0.2017.3.30+version: 0.2017.4.1 cabal-version: 1.12 build-type: Simple license: Apache@@ -16,17 +16,23 @@ library exposed-modules:- DBI- Poly- Xor- Util- Lang+ DDF.Bool+ DDF.Combine+ DDF.DBI+ DDF.Eval+ DDF.GWDiff+ DDF.ImportMeta+ DDF.Lang+ DDF.Poly+ DDF.Show+ DDF.UnHOAS+ DDF.Util+ DDF.Xor build-depends: base >= 4.9.0.0 && <= 4.9.1.0, mtl -any, random -any, constraints -any - hs-source-dirs: lib ghc-options: -ferror-spans default-language: Haskell2010
− lib/DBI.hs
@@ -1,246 +0,0 @@-{-# LANGUAGE - MultiParamTypeClasses, - RankNTypes, - ScopedTypeVariables, - FlexibleInstances, - FlexibleContexts, - UndecidableInstances, - PolyKinds, - LambdaCase, - NoMonomorphismRestriction, - TypeFamilies, - LiberalTypeSynonyms, - FunctionalDependencies, - ExistentialQuantification, - InstanceSigs, - TupleSections, - ConstraintKinds, - DefaultSignatures, - UndecidableSuperClasses, - TypeOperators, - TypeApplications, - PartialTypeSignatures #-} - -module DBI where -import qualified Prelude as P -import Prelude (($), (.), (+), (-), (++), show, (>>=), (*), (/), undefined) -import Util -import Control.Monad (when) -import System.Random -import Data.Proxy -import Data.Constraint -import Data.Constraint.Forall - -class Monoid r m where - zero :: r h m - plus :: r h (m -> m -> m) - -class Monoid repr w => WithDiff repr w where - withDiff :: repr h ((w -> x) -> w -> Diff x w) - -withDiff1 = app withDiff - -selfWithDiff :: (DBI repr, WithDiff repr w) => repr h (w -> Diff w w) -selfWithDiff = withDiff1 id - -instance Random () where - random = ((),) - randomR _ = random - -instance (Random l, Random r) => Random (l, r) where - random g0 = ((l, r), g2) - where - (l, g1) = random g0 - (r, g2) = random g1 - randomR ((llo, rlo), (lhi, rhi)) g0 = ((l, r), g2) - where - (l, g1) = randomR (llo, lhi) g0 - (r, g2) = randomR (rlo, rhi) g1 - -class DBI repr where - z :: repr (a, h) a - s :: repr h b -> repr (a, h) b - abs :: repr (a, h) b -> repr h (a -> b) - app :: repr h (a -> b) -> repr h a -> repr h b - hoas :: (repr (a, h) a -> repr (a, h) b) -> repr h (a -> b) - hoas f = abs $ f z - com :: repr h ((b -> c) -> (a -> b) -> (a -> c)) - com = lam3 $ \f g x -> app f (app g x) - flip :: repr h ((a -> b -> c) -> (b -> a -> c)) - flip = lam3 $ \f b a -> app2 f a b - id :: repr h (a -> a) - id = lam $ \x -> x - const :: repr h (a -> b -> a) - const = lam2 $ \x _ -> x - scomb :: repr h ((a -> b -> c) -> (a -> b) -> (a -> c)) - scomb = lam3 $ \f x arg -> app2 f arg (app x arg) - dup :: repr h ((a -> a -> b) -> (a -> b)) - dup = lam2 $ \f x -> app2 f x x - let_ :: repr h (a -> (a -> b) -> b) - let_ = flip1 id - -const1 = app const -map2 = app2 map -return = pure -bind2 = app2 bind -map1 = app map -join1 = app join -bimap2 = app2 bimap -flip1 = app flip -flip2 = app2 flip - -class Functor r f where - map :: r h ((a -> b) -> (f a -> f b)) - -class Functor r a => Applicative r a where - pure :: r h (x -> a x) - ap :: r h (a (x -> y) -> a x -> a y) - -class (DBI r, Applicative r m) => Monad r m where - bind :: r h (m a -> (a -> m b) -> m b) - join :: r h (m (m a) -> m a) - join = lam $ \m -> bind2 m id - bind = lam2 $ \m f -> join1 (app2 map f m) - {-# MINIMAL (join | bind) #-} - -class BiFunctor r p where - bimap :: r h ((a -> b) -> (c -> d) -> p a c -> p b d) - -app3 f x y z = app (app2 f x y) z -com2 = app2 com - -newtype Eval h x = Eval {runEval :: h -> x} - -comb = Eval . P.const - -instance DBI Eval where - z = Eval P.fst - s (Eval a) = Eval $ a . P.snd - abs (Eval f) = Eval $ \a h -> f (h, a) - app (Eval f) (Eval x) = Eval $ \h -> f h $ x h - -data AST = Leaf P.String | App P.String AST [AST] | Lam P.String [P.String] AST - -appAST (Leaf f) x = App f x [] -appAST (App f x l) r = App f x (l ++ [r]) -appAST lam r = appAST (Leaf $ show lam) r - -lamAST str (Lam s l t) = Lam str (s:l) t -lamAST str r = Lam str [] r - -instance P.Show AST where - show (Leaf f) = f - show (App f x l) = "(" ++ f ++ " " ++ show x ++ P.concatMap ((" " ++) . show) l ++ ")" - show (Lam s l t) = "(\\" ++ s ++ P.concatMap (" " ++) l ++ " -> " ++ show t ++ ")" - -newtype Show h a = Show {runShow :: [P.String] -> P.Int -> AST} -name = Show . P.const . P.const . Leaf - -instance DBI Show where - z = Show $ P.const $ Leaf . show . P.flip (-) 1 - s (Show v) = Show $ \vars -> v vars . P.flip (-) 1 - abs (Show f) = Show $ \vars x -> lamAST (show x) (f vars (x + 1)) - app (Show f) (Show x) = Show $ \vars h -> appAST (f vars h) (x vars h) - hoas f = Show $ \(v:vars) h -> - lamAST v (runShow (f $ Show $ P.const $ P.const $ Leaf v) vars (h + 1)) - -class NT repr l r where - conv :: repr l t -> repr r t - -class NTS repr l r where - convS :: repr l t -> repr r t - -instance (DBI repr, NT repr l r) => NTS repr l (a, r) where - convS = s . conv - -instance {-# OVERLAPPABLE #-} NTS repr l r => NT repr l r where - conv = convS - -instance {-# OVERLAPPING #-} NT repr x x where - conv = P.id - -lam :: forall repr a b h. DBI repr => - ((forall k. NT repr (a, h) k => repr k a) -> (repr (a, h)) b) -> repr h (a -> b) -lam f = hoas (\x -> f $ conv x) - -lam2 :: forall repr a b c h. DBI repr => - ((forall k. NT repr (a, h) k => repr k a) -> (forall k. NT repr (b, (a, h)) k => repr k b) -> (repr (b, (a, h))) c) -> repr h (a -> b -> c) -lam2 f = lam $ \x -> lam $ \y -> f x y - -lam3 f = lam2 $ \x y -> lam $ \z -> f x y z - -type family Diff v x -type instance Diff v () = () -type instance Diff v (a -> b) = Diff v a -> Diff v b -type instance Diff v (a, b) = (Diff v a, Diff v b) - -newtype WDiff repr v h x = WDiff {runWDiff :: repr (Diff v h) (Diff v x)} - -app2 f a = app (app f a) - -plus2 = app2 plus - -instance DBI repr => DBI (WDiff repr v) where - z = WDiff z - s (WDiff x) = WDiff $ s x - abs (WDiff f) = WDiff $ abs f - app (WDiff f) (WDiff x) = WDiff $ app f x - hoas f = WDiff $ hoas (runWDiff . f . WDiff) - -noEnv :: repr () x -> repr () x -noEnv = P.id - -class RandRange w where - randRange :: (P.Double, P.Double) -> (w, w) - -instance RandRange () where - randRange _ = ((), ()) - -instance RandRange P.Double where - randRange (lo, hi) = (lo, hi) - -instance (RandRange l, RandRange r) => RandRange (l, r) where - randRange (lo, hi) = ((llo, rlo), (lhi, rhi)) - where - (llo, lhi) = randRange (lo, hi) - (rlo, rhi) = randRange (lo, hi) - -instance Weight () where weightCon = Sub Dict - -instance Weight P.Double where weightCon = Sub Dict - -instance (Weight l, Weight r) => Weight (l, r) where - weightCon :: forall con. (con (), con P.Double, ForallV (ProdCon con)) :- con (l, r) - weightCon = Sub (mapDict (prodCon \\ (instV :: (ForallV (ProdCon con) :- ProdCon con l r))) (Dict \\ weightCon @l @con \\ weightCon @r @con)) - -class ProdCon con l r where - prodCon :: (con l, con r) :- con (l, r) - -instance ProdCon Random l r where prodCon = Sub Dict - -instance ProdCon RandRange l r where prodCon = Sub Dict - -instance ProdCon P.Show l r where prodCon = Sub Dict - -class Weight w where - weightCon :: (con (), con P.Double, ForallV (ProdCon con)) :- con w - -data RunImpW repr h x = forall w. Weight w => RunImpW (repr h (w -> x)) -data ImpW repr h x = NoImpW (repr h x) | forall w. Weight w => ImpW (repr h (w -> x)) - -type RunImpWR repr h x = forall r. (forall w. Weight w => repr h (w -> x) -> r) -> r - -runImpW2RunImpWR :: RunImpW repr h x -> RunImpWR repr h x -runImpW2RunImpWR (RunImpW x) = \f -> f x - -runImpWR2RunImpW :: RunImpWR repr h x -> RunImpW repr h x -runImpWR2RunImpW f = f RunImpW - -data Combine l r h x = Combine (l h x) (r h x) - -instance (DBI l, DBI r) => DBI (Combine l r) where - z = Combine z z - s (Combine l r) = Combine (s l) (s r) - app (Combine fl fr) (Combine xl xr) = Combine (app fl xl) (app fr xr) - abs (Combine l r) = Combine (abs l) (abs r) - hoas f = Combine (hoas $ \x -> case f (Combine x z) of Combine l r -> l) (hoas $ \x -> case f (Combine z x) of Combine l r -> r)
− lib/Lang.hs
@@ -1,587 +0,0 @@-{-# LANGUAGE- MultiParamTypeClasses,- RankNTypes,- ScopedTypeVariables,- FlexibleInstances,- FlexibleContexts,- UndecidableInstances,- PolyKinds,- LambdaCase,- NoMonomorphismRestriction,- TypeFamilies,- LiberalTypeSynonyms,- FunctionalDependencies,- ExistentialQuantification,- InstanceSigs,- TupleSections,- ConstraintKinds,- DefaultSignatures,- UndecidableSuperClasses,- TypeOperators,- TypeApplications,- PartialTypeSignatures #-}--module Lang where-import DBI-import qualified Prelude as P-import Prelude (($), (.), (+), (-), (++), show, (>>=), (*), (/), undefined)-import qualified Control.Monad.Writer as P-import qualified Data.Functor.Identity as P-import qualified GHC.Float as P-import qualified Data.Tuple as P-import Data.Void-import Data.Proxy-import Data.Proxy-import Data.Constraint-import Data.Constraint.Forall--type instance Diff v (P.Writer w a) = P.Writer (Diff v w) (Diff v a)-type instance Diff v Void = Void-type instance Diff v P.Double = (P.Double, v)-type instance Diff v P.Float = (P.Float, v)-type instance Diff v (P.Either a b) = P.Either (Diff v a) (Diff v b)-type instance Diff v (P.Maybe a) = P.Maybe (Diff v a)-type instance Diff v (P.IO a) = P.IO (Diff v a)-type instance Diff v [a] = [Diff v a]--class DBI repr => Lang repr where- mkProd :: repr h (a -> b -> (a, b))- zro :: repr h ((a, b) -> a)- fst :: repr h ((a, b) -> b)- double :: P.Double -> repr h P.Double- doubleZero :: repr h P.Double- doubleZero = double 0- doubleOne :: repr h P.Double- doubleOne = double 1- doublePlus :: repr h (P.Double -> P.Double -> P.Double)- doubleMinus :: repr h (P.Double -> P.Double -> P.Double)- doubleMult :: repr h (P.Double -> P.Double -> P.Double)- doubleDivide :: repr h (P.Double -> P.Double -> P.Double)- doubleExp :: repr h (P.Double -> P.Double)- float :: P.Float -> repr h P.Float- floatZero :: repr h P.Float- floatZero = float 0- floatOne :: repr h P.Float- floatOne = float 1- floatPlus :: repr h (P.Float -> P.Float -> P.Float)- floatMinus :: repr h (P.Float -> P.Float -> P.Float)- floatMult :: repr h (P.Float -> P.Float -> P.Float)- floatDivide :: repr h (P.Float -> P.Float -> P.Float)- floatExp :: repr h (P.Float -> P.Float)- fix :: repr h ((a -> a) -> a)- left :: repr h (a -> P.Either a b)- right :: repr h (b -> P.Either a b)- sumMatch :: repr h ((a -> c) -> (b -> c) -> P.Either a b -> c)- unit :: repr h ()- exfalso :: repr h (Void -> a)- nothing :: repr h (P.Maybe a)- just :: repr h (a -> P.Maybe a)- optionMatch :: repr h (b -> (a -> b) -> P.Maybe a -> b)- ioRet :: repr h (a -> P.IO a)- ioBind :: repr h (P.IO a -> (a -> P.IO b) -> P.IO b)- ioMap :: repr h ((a -> b) -> P.IO a -> P.IO b)- nil :: repr h [a]- cons :: repr h (a -> [a] -> [a])- listMatch :: repr h (b -> (a -> [a] -> b) -> [a] -> b)- listAppend :: repr h ([a] -> [a] -> [a])- listAppend = lam2 $ \l r -> fix2 (lam $ \self -> listMatch2 r (lam2 $ \a as -> cons2 a (app self as))) l- writer :: repr h ((a, w) -> P.Writer w a)- runWriter :: repr h (P.Writer w a -> (a, w))- swap :: repr h ((l, r) -> (r, l))- swap = lam $ \p -> mkProd2 (fst1 p) (zro1 p)- curry :: repr h (((a, b) -> c) -> (a -> b -> c))- uncurry :: repr h ((a -> b -> c) -> ((a, b) -> c))- curry = lam3 $ \f a b -> app f (mkProd2 a b)- uncurry = lam2 $ \f p -> app2 f (zro1 p) (fst1 p)- float2Double :: repr h (P.Float -> P.Double)- double2Float :: repr h (P.Double -> P.Float)--class Reify repr x where- reify :: x -> repr h x--instance Lang repr => Reify repr () where- reify _ = unit--instance Lang repr => Reify repr P.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 Eval where- zro = comb P.fst- fst = comb P.snd- mkProd = comb (,)- double = comb- doublePlus = comb (+)- doubleMinus = comb (-)- doubleMult = comb (*)- doubleDivide = comb (/)- fix = comb loop- where loop x = x $ loop x- left = comb P.Left- right = comb P.Right- sumMatch = comb $ \l r -> \case- P.Left x -> l x- P.Right x -> r x- unit = comb ()- exfalso = comb absurd- nothing = comb P.Nothing- just = comb P.Just- ioRet = comb P.return- ioBind = comb (>>=)- nil = comb []- cons = comb (:)- listMatch = comb $ \l r -> \case- [] -> l- x:xs -> r x xs- optionMatch = comb $ \l r -> \case- P.Nothing -> l- P.Just x -> r x- ioMap = comb P.fmap- writer = comb (P.WriterT . P.Identity)- runWriter = comb P.runWriter- doubleExp = comb P.exp- float = comb- floatPlus = comb (+)- floatMinus = comb (-)- floatMult = comb (*)- floatDivide = comb (/)- floatExp = comb P.exp- float2Double = comb P.float2Double- double2Float = comb P.double2Float--newtype UnHOAS repr h x = UnHOAS {runUnHOAS :: repr h x}--instance DBI repr => DBI (UnHOAS repr) where- z = UnHOAS z- s (UnHOAS x) = UnHOAS $ s x- abs (UnHOAS x) = UnHOAS $ abs x- app (UnHOAS f) (UnHOAS x) = UnHOAS $ app f x--instance Lang repr => Lang (UnHOAS repr) where- mkProd = UnHOAS mkProd- zro = UnHOAS zro- fst = UnHOAS fst- double = UnHOAS . double- doublePlus = UnHOAS doublePlus- doubleMinus = UnHOAS doubleMinus- doubleMult = UnHOAS doubleMult- doubleDivide = UnHOAS doubleDivide- doubleExp = UnHOAS doubleExp- fix = UnHOAS fix- left = UnHOAS left- right = UnHOAS right- sumMatch = UnHOAS sumMatch- unit = UnHOAS unit- exfalso = UnHOAS exfalso- nothing = UnHOAS nothing- just = UnHOAS just- ioRet = UnHOAS ioRet- ioBind = UnHOAS ioBind- nil = UnHOAS nil- cons = UnHOAS cons- listMatch = UnHOAS listMatch- optionMatch = UnHOAS optionMatch- ioMap = UnHOAS ioMap- writer = UnHOAS writer- runWriter = UnHOAS runWriter- float = UnHOAS . float- floatPlus = UnHOAS floatPlus- floatMinus = UnHOAS floatMinus- floatMult = UnHOAS floatMult- floatDivide = UnHOAS floatDivide- floatExp = UnHOAS floatExp- float2Double = UnHOAS float2Double- double2Float = UnHOAS double2Float--instance Lang Show where- mkProd = name "mkProd"- zro = name "zro"- fst = name "fst"- double = name . show- doublePlus = name "plus"- doubleMinus = name "minus"- doubleMult = name "mult"- doubleDivide = name "divide"- doubleExp = name "exp"- fix = name "fix"- left = name "left"- right = name "right"- sumMatch = name "sumMatch"- unit = name "unit"- exfalso = name "exfalso"- nothing = name "nothing"- just = name "just"- ioRet = name "ioRet"- ioBind = name "ioBind"- nil = name "nil"- cons = name "cons"- listMatch = name "listMatch"- optionMatch = name "optionMatch"- ioMap = name "ioMap"- writer = name "writer"- runWriter = name "runWriter"- float = name . show- floatPlus = name "plus"- floatMinus = name "minus"- floatMult = name "mult"- floatDivide = name "divide"- floatExp = name "exp"- float2Double = name "float2Double"- double2Float = name "double2Float"--instance Lang repr => Lang (GWDiff repr) where- mkProd = GWDiff (P.const mkProd)- zro = GWDiff $ P.const $ zro- fst = GWDiff $ P.const $ fst- double x = GWDiff $ P.const $ mkProd2 (double x) zero- doublePlus = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))- doubleMinus = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))- doubleMult = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (mult2 (zro1 l) (zro1 r))- (plus2 (mult2 (zro1 l) (fst1 r)) (mult2 (zro1 r) (fst1 l)))- doubleDivide = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (divide2 (zro1 l) (zro1 r))- (divide2 (minus2 (mult2 (zro1 r) (fst1 l)) (mult2 (zro1 l) (fst1 r)))- (mult2 (zro1 r) (zro1 r)))- doubleExp = GWDiff $ P.const $ lam $ \x -> mkProd2 (doubleExp1 (zro1 x)) (mult2 (doubleExp1 (zro1 x)) (fst1 x))- fix = GWDiff $ P.const fix- left = GWDiff $ P.const left- right = GWDiff $ P.const right- sumMatch = GWDiff $ P.const sumMatch- unit = GWDiff $ P.const unit- exfalso = GWDiff $ P.const exfalso- nothing = GWDiff $ P.const nothing- just = GWDiff $ P.const just- ioRet = GWDiff $ P.const ioRet- ioBind = GWDiff $ P.const ioBind- nil = GWDiff $ P.const nil- cons = GWDiff $ P.const cons- listMatch = GWDiff $ P.const listMatch- optionMatch = GWDiff $ P.const optionMatch- ioMap = GWDiff $ P.const ioMap- writer = GWDiff $ P.const writer- runWriter = GWDiff $ P.const runWriter- float x = GWDiff $ P.const $ mkProd2 (float x) zero- floatPlus = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))- floatMinus = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))- floatMult = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (mult2 (float2Double1 (zro1 l)) (zro1 r))- (plus2 (mult2 (float2Double1 (zro1 l)) (fst1 r)) (mult2 (float2Double1 (zro1 r)) (fst1 l)))- floatDivide = GWDiff $ P.const $ lam2 $ \l r ->- mkProd2 (divide2 (zro1 l) (float2Double1 (zro1 r)))- (divide2 (minus2 (mult2 (float2Double1 (zro1 r)) (fst1 l)) (mult2 (float2Double1 (zro1 l)) (fst1 r)))- (float2Double1 (mult2 (float2Double1 (zro1 r)) (zro1 r))))- floatExp = GWDiff $ P.const $ lam $ \x -> mkProd2 (floatExp1 (zro1 x)) (mult2 (float2Double1 (floatExp1 (zro1 x))) (fst1 x))- float2Double = GWDiff $ P.const $ bimap2 float2Double id- double2Float = GWDiff $ P.const $ bimap2 double2Float id--instance (Vector repr v, Lang repr) => Lang (WDiff repr v) where- mkProd = WDiff mkProd- zro = WDiff zro- fst = WDiff fst- double x = WDiff $ mkProd2 (double x) zero- doublePlus = WDiff $ lam2 $ \l r ->- mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))- doubleMinus = WDiff $ lam2 $ \l r ->- mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))- doubleMult = WDiff $ lam2 $ \l r ->- mkProd2 (mult2 (zro1 l) (zro1 r))- (plus2 (mult2 (zro1 l) (fst1 r)) (mult2 (zro1 r) (fst1 l)))- doubleDivide = WDiff $ lam2 $ \l r ->- mkProd2 (divide2 (zro1 l) (zro1 r))- (divide2 (minus2 (mult2 (zro1 r) (fst1 l)) (mult2 (zro1 l) (fst1 r)))- (mult2 (zro1 r) (zro1 r)))- doubleExp = WDiff $ lam $ \x -> mkProd2 (doubleExp1 (zro1 x)) (mult2 (doubleExp1 (zro1 x)) (fst1 x))- fix = WDiff fix- left = WDiff left- right = WDiff right- sumMatch = WDiff sumMatch- unit = WDiff unit- exfalso = WDiff exfalso- nothing = WDiff nothing- just = WDiff just- ioRet = WDiff ioRet- ioBind = WDiff ioBind- nil = WDiff nil- cons = WDiff cons- listMatch = WDiff listMatch- optionMatch = WDiff optionMatch- ioMap = WDiff ioMap- writer = WDiff writer- runWriter = WDiff runWriter- float x = WDiff $ mkProd2 (float x) zero- floatPlus = WDiff $ lam2 $ \l r ->- mkProd2 (plus2 (zro1 l) (zro1 r)) (plus2 (fst1 l) (fst1 r))- floatMinus = WDiff $ lam2 $ \l r ->- mkProd2 (minus2 (zro1 l) (zro1 r)) (minus2 (fst1 l) (fst1 r))- floatMult = WDiff $ lam2 $ \l r ->- mkProd2 (mult2 (float2Double1 (zro1 l)) (zro1 r))- (plus2 (mult2 (float2Double1 (zro1 l)) (fst1 r)) (mult2 (float2Double1 (zro1 r)) (fst1 l)))- floatDivide = WDiff $ lam2 $ \l r ->- mkProd2 (divide2 (zro1 l) (float2Double1 (zro1 r)))- (divide2 (minus2 (mult2 (float2Double1 (zro1 r)) (fst1 l)) (mult2 (float2Double1 (zro1 l)) (fst1 r)))- (float2Double1 (mult2 (float2Double1 (zro1 r)) (zro1 r))))- floatExp = WDiff $ lam $ \x -> mkProd2 (floatExp1 (zro1 x)) (mult2 (float2Double1 (floatExp1 (zro1 x))) (fst1 x))- float2Double = WDiff $ bimap2 float2Double id- double2Float = WDiff $ bimap2 double2Float id--instance Lang repr => ProdCon (Monoid repr) l r where prodCon = Sub Dict--instance Lang repr => ProdCon (WithDiff 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--instance Lang repr => Lang (ImpW repr) where- nil = NoImpW nil- cons = NoImpW cons- listMatch = NoImpW listMatch- zro = NoImpW zro- fst = NoImpW fst- mkProd = NoImpW mkProd- ioRet = NoImpW ioRet- ioMap = NoImpW ioMap- ioBind = NoImpW ioBind- unit = NoImpW unit- nothing = NoImpW nothing- just = NoImpW just- optionMatch = NoImpW optionMatch- exfalso = NoImpW exfalso- fix = NoImpW fix- left = NoImpW left- right = NoImpW right- sumMatch = NoImpW sumMatch- writer = NoImpW writer- runWriter = NoImpW runWriter- double = NoImpW . double- doubleExp = NoImpW doubleExp- doublePlus = NoImpW doublePlus- doubleMinus = NoImpW doubleMinus- doubleMult = NoImpW doubleMult- doubleDivide = NoImpW doubleDivide- float = NoImpW . float- floatExp = NoImpW floatExp- floatPlus = NoImpW floatPlus- floatMinus = NoImpW floatMinus- floatMult = NoImpW floatMult- floatDivide = NoImpW floatDivide- float2Double = NoImpW float2Double- double2Float = NoImpW double2Float--instance (Lang l, Lang r) => Lang (Combine l r) where- mkProd = Combine mkProd mkProd- zro = Combine zro zro- fst = Combine fst fst- double x = Combine (double x) (double x)- doublePlus = Combine doublePlus doublePlus- doubleMinus = Combine doubleMinus doubleMinus- doubleMult = Combine doubleMult doubleMult- doubleDivide = Combine doubleDivide doubleDivide- doubleExp = Combine doubleExp doubleExp- float x = Combine (float x) (float x)- floatPlus = Combine floatPlus floatPlus- floatMinus = Combine floatMinus floatMinus- floatMult = Combine floatMult floatMult- floatDivide = Combine floatDivide floatDivide- floatExp = Combine floatExp floatExp- fix = Combine fix fix- left = Combine left left- right = Combine right right- sumMatch = Combine sumMatch sumMatch- unit = Combine unit unit- exfalso = Combine exfalso exfalso- nothing = Combine nothing nothing- just = Combine just just- optionMatch = Combine optionMatch optionMatch- ioRet = Combine ioRet ioRet- ioBind = Combine ioBind ioBind- ioMap = Combine ioMap ioMap- nil = Combine nil nil- cons = Combine cons cons- listMatch = Combine listMatch listMatch- runWriter = Combine runWriter runWriter- writer = Combine writer writer- double2Float = Combine double2Float double2Float- float2Double = Combine float2Double float2Double--instance Lang repr => WithDiff repr () where- withDiff = const1 id--instance Lang repr => WithDiff repr P.Double where- withDiff = lam2 $ \conv d -> mkProd2 d (app conv doubleOne)--instance (Lang repr, WithDiff repr l, WithDiff repr r) => WithDiff repr (l, r) where- withDiff = lam $ \conv -> bimap2 (withDiff1 (lam $ \l -> app conv (mkProd2 l zero))) (withDiff1 (lam $ \r -> app conv (mkProd2 zero r)))--class Monoid r g => Group r g where- invert :: r h (g -> g)- minus :: r h (g -> g -> g)- default invert :: Lang r => r h (g -> g)- invert = minus1 zero- default minus :: Lang r => r h (g -> g -> g)- minus = lam2 $ \x y -> plus2 x (invert1 y)- {-# MINIMAL (invert | minus) #-}--class Group r v => Vector r v where- mult :: r h (P.Double -> v -> v)- divide :: r h (v -> P.Double -> v)- default mult :: Lang r => r h (P.Double -> v -> v)- mult = lam2 $ \x y -> divide2 y (recip1 x)- default divide :: Lang r => r h (v -> P.Double -> v)- divide = lam2 $ \x y -> mult2 (recip1 y) x- {-# MINIMAL (mult | divide) #-}--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 Lang r => Monoid r P.Double where- zero = doubleZero- plus = doublePlus--instance Lang r => Group r P.Double where- minus = doubleMinus--instance Lang r => Vector r P.Double where- mult = doubleMult- divide = doubleDivide--instance Lang r => Monoid r P.Float where- zero = floatZero- plus = floatPlus--instance Lang r => Group r P.Float where- minus = floatMinus--instance Lang r => Vector r P.Float where- mult = com2 floatMult double2Float- divide = com2 (flip2 com double2Float) floatDivide--instance (Lang 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 (Lang repr, Group repr l, Group repr r) => Group repr (l, r) where- invert = bimap2 invert invert--instance (Lang repr, Vector repr l, Vector repr r) => Vector repr (l, r) where- mult = lam $ \x -> bimap2 (mult1 x) (mult1 x)--instance (Lang repr, Monoid repr l, Monoid repr r) => Monoid repr (l -> r) where- zero = const1 zero- plus = lam3 $ \l r x -> plus2 (app l x) (app r x)--instance (Lang repr, Group repr l, Group repr r) => Group repr (l -> r) where- invert = lam2 $ \l x -> app l (invert1 x)--instance (Lang repr, Vector repr l, Vector repr r) => Vector repr (l -> r) 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 (,) where- bimap = lam3 $ \l r p -> mkProd2 (app l (zro1 p)) (app r (fst1 p))--instance Lang r => Functor r (P.Writer w) where- map = lam $ \f -> com2 writer (com2 (bimap2 f id) runWriter)--instance (Lang r, Monoid r w) => Applicative r (P.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 (P.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 P.IO where- map = ioMap--instance Lang r => Applicative r P.IO where- pure = ioRet- ap = lam2 $ \f x -> ioBind2 f (flip2 ioMap x)--instance Lang r => Monad r P.IO where- bind = ioBind--instance Lang r => Functor r P.Maybe where- map = lam $ \func -> optionMatch2 nothing (com2 just func)--instance Lang r => Applicative r P.Maybe where- pure = just- ap = optionMatch2 (const1 nothing) map--instance Lang r => Monad r P.Maybe where- bind = lam2 $ \x func -> optionMatch3 nothing func x--runImpW :: forall repr h x. Lang repr => ImpW repr h x -> RunImpW repr h x-runImpW (ImpW x) = RunImpW x-runImpW (NoImpW x) = RunImpW (const1 x :: repr h (() -> x))--newtype GWDiff repr h x = GWDiff {runGWDiff :: forall v. Vector repr v => Proxy v -> repr (Diff v h) (Diff v x)}--instance DBI repr => DBI (GWDiff repr) where- z = GWDiff (P.const z)- s (GWDiff x) = GWDiff (\p -> s $ x p)- app (GWDiff f) (GWDiff x) = GWDiff (\p -> app (f p) (x p))- abs (GWDiff x) = GWDiff (\p -> abs $ x p)--cons2 = app2 cons-listMatch2 = app2 listMatch-fix1 = app fix-fix2 = app2 fix-uncurry1 = app uncurry-optionMatch2 = app2 optionMatch-optionMatch3 = app3 optionMatch-zro1 = app zro-fst1 = app fst-mult1 = app mult-mult2 = app2 mult-divide2 = app2 divide-invert1 = app invert-mkProd1 = app mkProd-mkProd2 = app2 mkProd-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--instance Lang repr => DBI (ImpW repr) where- z = NoImpW z- s :: forall a h b. ImpW repr h b -> ImpW repr (a, h) b- s (ImpW x) = work x- where- work :: Weight w => repr h (w -> b) -> ImpW repr (a, h) b- work x = ImpW (s x)- s (NoImpW x) = NoImpW (s x)- app (ImpW f) (ImpW x) = ImpW (lam $ \p -> app (app (conv f) (zro1 p)) (app (conv x) (fst1 p)))- app (NoImpW f) (NoImpW x) = NoImpW (app f x)- app (ImpW f) (NoImpW x) = ImpW (lam $ \w -> app2 (conv f) w (conv x))- app (NoImpW f) (ImpW x) = ImpW (lam $ \w -> app (conv f) (app (conv x) w))- abs (ImpW f) = ImpW (flip1 $ abs f)- abs (NoImpW x) = NoImpW (abs x)
− lib/Poly.lhs
@@ -1,107 +0,0 @@-> {-# LANGUAGE -> MultiParamTypeClasses, -> RankNTypes, -> ScopedTypeVariables, -> FlexibleInstances, -> FlexibleContexts, -> UndecidableInstances, -> IncoherentInstances, -> PolyKinds, -> LambdaCase, -> NoMonomorphismRestriction, -> TypeFamilies, -> LiberalTypeSynonyms, -> EmptyCase #-} - -> module Poly where -> import Control.Monad (when) -> import Util -> import DBI hiding (return) -> import Lang -> import qualified Control.Monad as P - -Importing files and opening language extension... -So, our goal is to find x, where x * x + 2 * x + 3 = 27. -To do so, we try to minimize their difference squared (l2 norm). - -> poly :: forall repr h. Lang repr => repr h (Double -> Double) -> poly = lam $ \x -> plus2 (mult2 x x) (plus2 (mult2 (double 2.0) x) (double 3.0)) - -poly x = x * x + (2 * x + 3) - -> l2 = lam $ \x -> mult2 (minus2 x (double 27)) (minus2 x (double 27)) - -l2 x = (x - 27) * (x - 27) -l2 measure how far is the input from 27 - -> comp = com2 l2 poly - -By composing the two, we can measure how far is x * x + 2 * x + 3 from 27. -We want to minimize this distance. - -Now write a generic function that calculate x and return it. - -> solve :: forall m. P.Monad m => (AST -> m ()) -> (Integer -> Double -> m ()) -> m Double -> solve doAST doIter = do - -Let's begin by trying to print poly - -> doAST $ runShow poly vars 0 -> go 0 0 -> where - -The main loop. i is step and w is weight (our current estimate of x). -We start by assuming x = 0 is the solution, -and minimize (comp x) by taking derivative of x, and decrease it whenever it is positive (and vice versa). - -> go :: Integer -> Double -> m Double -> go i w | i < 200 = do -> doIter i w -> go (1 + i) $ w - 0.001 * snd (runEval (runWDiff $ noEnv comp) () (w, 1)) - -noEnv comp assume the term (which is a De Brujin Index term) need no environment (is free) -and it is a finally tagless term, with WDiff interpreter being implicitly applied, -which return another finally tagless term, but taking derivative of x. -it is then applied to Eval interpreter (which eval it in the meta language, haskell). -similar to runWDiff, we use runEval to take out the term from a newtype -now we apply the environment (remember it has no environment? so just stick a unit) -and a pair, the zeroth being x, the first being derivative of x, which is 1. -the whole computation return a pair of (x * x + (2 * x + 3) - 27)^2, and it's derivative. -we modify w using the derivative. - -> go i w = return w - -By running the program, you shall see -(\a -> (plus (mult a a) (plus (mult 2.0 a) 3.0))) -since we pretty print poly -followed by something like -0.0 -9.6e-2 -0.43573084645674215 -1.1890033104995505 -2.498644212525056 -3.652210805402036 -3.9662181049468925 -3.9981203814732154 -3.9999338218043157 -3.999998509763363 -3.9999999785234146 -3.9999999998019136 -3.9999999999988307 -3.9999999999999956 -3.999999999999999 -which mean we found 4 as a soultion. -plugging it back to the equation, we can verify that (4 * 4) + 2 * 4 + 3 is indeed 27! - -Now the main function: - -> main :: IO () -> main = do -> d <- solve print printSquare -> putStrLn $ "x is: " ++ (show d) -> return () -> where -> printSquare i x = when (isSquare i) (print x) - -the only thing worth noting is that we print the weight in increasing interval, -so initially more weight is printed
− lib/Util.hs
@@ -1,6 +0,0 @@-module Util where - -vars = [pre : suf | suf <- "":map show [0..], pre <- ['a'..'z']] - -isSquare n = sq * sq == n - where sq = floor $ sqrt (fromIntegral n::Double)
− lib/Xor.lhs
@@ -1,127 +0,0 @@-> {-# LANGUAGE ScopedTypeVariables, NoMonomorphismRestriction, TypeApplications, RankNTypes #-}--This is the classical example of using sigmoid NN to approximate Xor.--> module Xor where-> import DBI hiding (return)-> import qualified Poly as YouShouldAlreadyReadThis-> import qualified Prelude as P-> import Prelude (Double, IO, return, ($), print, undefined, Int, (<=), (<), (+), (-), (*), (/), (++), fromIntegral, putStr)-> import Util-> import System.Random-> import Control.Monad (when)-> import Data.Proxy-> import Data.Constraint-> import Lang--Recall in poly, we constructed a function Double -> Double,-with argument being the weight, and do gradient descend to found a solution.--However, most of the time, there wil be more than one weight (or no weight at all).-Also, when we are composing a Neural Network to approximate a value, we dont really care how much weight it use.-So, we use existential type to hide the actual weight.--data ImpW repr h x = forall w. Weight w => ImpW (repr h (w -> x))--ImpW stands for implicit weights.-The existential w is weight, and a Neural Network of type x is just a function from w to x!-We require that the weight can be constructed randomly, so we have random initialization.-Weight also form a Vector so we can combine weights (update it), scale it (to control the learning rate).--Let's start by constructing a weight.--> weight :: Lang repr => ImpW repr h Double-> weight = ImpW id--Note that we are just manipulating AST.-If you wanna do weight sharing, you need to use let(in DDF) yourself.--Obviously, we just need to take the implicit argument.--We have the weight, now we need the activation function, sigmoid.--> sigmoid = lam $ \x -> recip1 (plus2 doubleOne (doubleExp1 (invert1 x)))-> sigmoid1 = app sigmoid--With weight and sigmoid we can construct a neuron of type ((Double, Double) -> Double)-The weight should be a pair of Double, each as a scale on the actual input, with a bias.-We then add the two scaled input, with the bias, and pass them into sigmoid.--> scaleAdd :: Lang repr => ImpW repr h ((Double, Double) -> Double)-> scaleAdd = ImpW $ lam2 $ \w p -> plus2 (mult2 (zro1 w) (zro1 p)) (plus2 (fst1 w) (fst1 p))--> withBias :: Lang repr => ImpW repr h (Double -> Double)-> withBias = ImpW $ plus--> neuron :: Lang repr => ImpW repr h ((Double, Double) -> Double)-> neuron = com2 (com2 sigmoid withBias) scaleAdd-> neuron1 = app neuron--Now, the hidden layer of type (Double, Double) -> ((Double, Double), (Double, Double))--> hidden = lam $ \p -> mkProd2 (mkProd2 (neuron1 p) (neuron1 p)) (mkProd2 (neuron1 p) (neuron1 p))--And finally, the whole NN:--> type XOR = (Double, Double) -> Double-> xor :: Lang repr => ImpW repr h XOR-> xor = neuron `com2` (bimap2 scaleAdd scaleAdd) `com2` hidden--But before we can train it, we need to define the dataset and the loss function.--> l2 :: Lang repr => repr h (Double -> Double -> Double)-> l2 = lam2 $ \l r -> (mult2 (minus2 l r) (minus2 l r))-> l22 = app2 l2--> eval :: Lang repr => repr h (XOR -> ((Double, Double), Double) -> Double)-> eval = lam2 $ \xor p -> l22 (app xor (zro1 p)) (fst1 p)--> dataset :: Lang repr => repr h [((Double, Double), Double)]-> dataset = cons2 (build 0 0 0) (cons2 (build 0 1 1) (cons2 (build 1 0 1) (cons2 (build 1 1 0) nil)))-> where build l r ret = mkProd2 (mkProd2 (double l) (double r)) (double ret)--However, unlike Poly, there are more than one datapoint, so we need to use a list, and map xor onto it.--> loss :: Lang repr => repr h (XOR -> Double)-> loss = lam $ \xor -> fix2 (lam $ \self -> listMatch2 doubleZero (lam2 $ \x xs -> plus2 x (app self xs))) (map2 (app eval xor) dataset)--Now we are good to implement the train function!--> findXor :: forall g m. (RandomGen g, P.Monad m) => g -> (AST -> m ()) -> (Int -> Double -> P.String -> m ()) -> m XOR-> findXor rand doAST doIter = case runImpW $ noEnv xor of-> RunImpW ((Combine (Show xorS) (Combine (Eval xorEv) xorE)) :: Weight w => Combine Show (Combine Eval (GWDiff Eval)) () (w -> XOR)) -> do-> doAST $ xorS vars 0--printing weights. now you will see a list of gibberish--> let initWeight :: w = P.fst $ ((randomR (randRange (-0.01, 0.01)) \\ weightCon @w @Random) \\ weightCon @w @RandRange) rand--Getting random weights...--> (go (diff xorE) initWeight (runEval selfWithDiff () \\ weightCon @w @(WithDiff Eval)) (diff loss)-> ((runEval (lam3 $ \d o n -> minus2 o (mult2 d n)) ()) \\ weightCon @w @(Vector Eval)) 0 (xorEv ())) \\ weightCon @w @P.Show-> where-> diff :: GWDiff Eval () x -> Diff w x-> diff x = (runEval (runGWDiff x (Proxy :: Proxy w)) ()) \\ weightCon @w @(Vector Eval)-> go :: P.Show w => (Diff w (w -> XOR)) -> w -> (w -> Diff w w) -> (Diff w (XOR -> Double)) -> (Double -> w -> w -> w) -> Int -> (w -> XOR) -> m XOR-> go xor weight reify loss update i orig | i <= 2500 = do-> doIter i lossVal (P.show weight)-> go xor (update 0.3 weight lossDiff) reify loss update (1 + i) orig-> where-> (lossVal, lossDiff) = loss $ xor (reify weight)-> go xor weight _ _ _ _ orig = return $ orig weight--> main :: IO ()-> main = do-> g <- getStdGen-> xor <- findXor g print (\i d w -> when (isSquare i) $ do-> print d-> P.putStrLn w-> P.putStrLn "")-> let doXor :: Double -> Double -> IO ()-> doXor l r = P.putStrLn $ P.show l ++ " xor " ++ P.show r ++ " is " ++ (P.show $ xor (l, r))-> doXor 0 0-> doXor 0 1-> doXor 1 0-> doXor 1 1-> return ()
test/TestPoly.hs view
@@ -1,6 +1,6 @@ module Main where -import Poly hiding (main)+import DDF.Poly hiding (main) import Control.Monad import System.Exit (exitFailure)
test/TestXor.hs view
@@ -1,7 +1,6 @@ module Main where -import Poly hiding (main)-import Xor hiding (main)+import DDF.Xor hiding (main) import Control.Monad import System.Exit (exitFailure) import System.Random