diff options
| author | Gregor Kleen <pngwjpgh@users.noreply.github.com> | 2016-08-05 01:24:28 +0200 |
|---|---|---|
| committer | Gregor Kleen <pngwjpgh@users.noreply.github.com> | 2016-08-05 01:24:28 +0200 |
| commit | 4a95e619dd206f9f3578d420500ee3824a413b33 (patch) | |
| tree | 2c48c0c514486fe94d80c14121469bf50cb647b5 | |
| parent | b16e56a555b37c5d0c01074b6c6a0dbcbb100bfe (diff) | |
| download | events-4a95e619dd206f9f3578d420500ee3824a413b33.tar events-4a95e619dd206f9f3578d420500ee3824a413b33.tar.gz events-4a95e619dd206f9f3578d420500ee3824a413b33.tar.bz2 events-4a95e619dd206f9f3578d420500ee3824a413b33.tar.xz events-4a95e619dd206f9f3578d420500ee3824a413b33.zip | |
Initial work on builtin constants
| -rw-r--r-- | events/src/Events/Spec.hs | 1 | ||||
| -rw-r--r-- | events/src/Events/Spec/Eval.hs | 49 | ||||
| -rw-r--r-- | events/src/Events/Spec/Parse.hs | 2 | ||||
| -rw-r--r-- | events/src/Events/Spec/Types.hs | 11 |
4 files changed, 49 insertions, 14 deletions
diff --git a/events/src/Events/Spec.hs b/events/src/Events/Spec.hs index cfa75be..c2a84ac 100644 --- a/events/src/Events/Spec.hs +++ b/events/src/Events/Spec.hs | |||
| @@ -4,6 +4,7 @@ module Events.Spec | |||
| 4 | ( interpret | 4 | ( interpret |
| 5 | , Spec, Cmnd(..), Expr(..), Elem(..) | 5 | , Spec, Cmnd(..), Expr(..), Elem(..) |
| 6 | , module Events.Spec.Parse | 6 | , module Events.Spec.Parse |
| 7 | , module Events.Spec.Eval | ||
| 7 | ) where | 8 | ) where |
| 8 | 9 | ||
| 9 | import Events.Spec.Types | 10 | import Events.Spec.Types |
diff --git a/events/src/Events/Spec/Eval.hs b/events/src/Events/Spec/Eval.hs index 3a23e0b..24cfeb6 100644 --- a/events/src/Events/Spec/Eval.hs +++ b/events/src/Events/Spec/Eval.hs | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | {-# LANGUAGE GADTs, DataKinds, TypeOperators, RankNTypes, ScopedTypeVariables #-} | 1 | {-# LANGUAGE GADTs, DataKinds, TypeFamilies, TypeOperators, RankNTypes, ScopedTypeVariables #-} |
| 2 | {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} | ||
| 3 | {-# LANGUAGE InstanceSigs #-} | ||
| 2 | 4 | ||
| 3 | module Events.Spec.Eval | 5 | module Events.Spec.Eval |
| 4 | ( evalExpr | 6 | ( evalExpr |
| 7 | , Bindable(..) | ||
| 5 | ) where | 8 | ) where |
| 6 | 9 | ||
| 7 | import Events.Spec.Types | 10 | import Events.Spec.Types |
| @@ -11,10 +14,11 @@ shift = shift' LZ | |||
| 11 | where | 14 | where |
| 12 | -- shift' :: forall ts1 ts2 t x. Length ts1 -> Expr (ts1 ++ ts2) x -> Expr (ts1 ++ t ': ts2) x | 15 | -- shift' :: forall ts1 ts2 t x. Length ts1 -> Expr (ts1 ++ ts2) x -> Expr (ts1 ++ t ': ts2) x |
| 13 | shift' :: forall ts1 x. Length ts1 -> Expr m (ts1 ++ ts2) x -> Expr m (ts1 ++ t ': ts2) x | 16 | shift' :: forall ts1 x. Length ts1 -> Expr m (ts1 ++ ts2) x -> Expr m (ts1 ++ t ': ts2) x |
| 14 | shift' _ (ELit x) = ELit x | 17 | shift' LZ (EPri f) = EPri $ const (EPri f) |
| 15 | shift' l (EVar v) = EVar $ shiftElem l v | 18 | shift' (LS l) (EPri f) = EPri $ shift' l . f |
| 16 | shift' l (ELam b) = ELam $ shift' (LS l) b | 19 | shift' l (EVar v) = EVar $ shiftElem l v |
| 17 | shift' l (EApp f x) = EApp (shift' l f) (shift' l x) | 20 | shift' l (ELam b) = ELam $ shift' (LS l) b |
| 21 | shift' l (EApp f x) = EApp (shift' l f) (shift' l x) | ||
| 18 | 22 | ||
| 19 | shiftElem :: forall ts1 u. Length ts1 -> Elem u (ts1 ++ ts2) -> Elem u (ts1 ++ t ': ts2) | 23 | shiftElem :: forall ts1 u. Length ts1 -> Elem u (ts1 ++ ts2) -> Elem u (ts1 ++ t ': ts2) |
| 20 | shiftElem LZ e = ES e | 24 | shiftElem LZ e = ES e |
| @@ -24,7 +28,8 @@ shift = shift' LZ | |||
| 24 | 28 | ||
| 25 | beta = flip beta' LZ | 29 | beta = flip beta' LZ |
| 26 | beta' :: forall m ts1 ts2 s t. Expr m ts2 s -> Length ts1 -> Expr m (ts1 ++ s ': ts2) t -> Expr m (ts1 ++ ts2) t | 30 | beta' :: forall m ts1 ts2 s t. Expr m ts2 s -> Length ts1 -> Expr m (ts1 ++ s ': ts2) t -> Expr m (ts1 ++ ts2) t |
| 27 | beta' _ _ (ELit x) = ELit x | 31 | beta' e LZ (EPri f) = EApp (ELam (EPri f)) e |
| 32 | beta' e (LS l) (EPri f) = EPri (beta' e l . f) | ||
| 28 | beta' e LZ (EVar EZ ) = e | 33 | beta' e LZ (EVar EZ ) = e |
| 29 | beta' _ LZ (EVar (ES v)) = EVar v | 34 | beta' _ LZ (EVar (ES v)) = EVar v |
| 30 | beta' _ (LS _) (EVar EZ ) = EVar EZ | 35 | beta' _ (LS _) (EVar EZ ) = EVar EZ |
| @@ -33,6 +38,32 @@ beta' e l (ELam b) = ELam $ beta' e (LS l) b | |||
| 33 | beta' e l (EApp f a) = EApp (beta' e l f) (beta' e l a) | 38 | beta' e l (EApp f a) = EApp (beta' e l f) (beta' e l a) |
| 34 | 39 | ||
| 35 | evalExpr :: Expr m '[] t -> Val m t | 40 | evalExpr :: Expr m '[] t -> Val m t |
| 36 | evalExpr (ELit a) = a | 41 | evalExpr (EVal a) = a |
| 37 | evalExpr (ELam a) = a | 42 | evalExpr (ELam a) = a |
| 38 | evalExpr (EApp f a) = evalExpr $ beta a (evalExpr f) | 43 | evalExpr (EApp (ELam (EPri f)) a) = evalExpr . f $ evalExpr a |
| 44 | evalExpr (EApp f a) = evalExpr $ beta a (evalExpr f) | ||
| 45 | |||
| 46 | -- liftE :: (Val m a -> Val m b) -> Expr m (a ': ctx) b | ||
| 47 | -- liftE = EPri . (EVal .) | ||
| 48 | |||
| 49 | -- bindE :: (m a -> b) -> Expr m (a ': Ctx b) (Fin b) | ||
| 50 | -- bindE f = liftE $ bindE . f | ||
| 51 | |||
| 52 | type family Ctx f where | ||
| 53 | Ctx (a -> b) = (a ': Ctx b) | ||
| 54 | Ctx a = '[] | ||
| 55 | |||
| 56 | type family Fin f where | ||
| 57 | Fin (a -> b) = Fin b | ||
| 58 | Fin a = a | ||
| 59 | |||
| 60 | class Bindable m b where | ||
| 61 | bindE :: (Val m a -> m b) -> Expr m (a ': Ctx b) (Fin b) | ||
| 62 | |||
| 63 | instance {-# OVERLAPS #-} ((Val m b) ~ (m b), Applicative m, Bindable m c) => Bindable m (b -> c) where | ||
| 64 | bindE :: (Val m a -> m (b -> c)) -> Expr m (a ': b ': Ctx c) (Fin c) | ||
| 65 | bindE f = (EPri :: (Val m a -> Expr m (b ': Ctx c) (Fin c)) -> Expr m (a ': b ': Ctx c) (Fin c)) . ((bindE :: (Val m b -> m c) -> Expr m (b ': Ctx c) (Fin c)) . ) $ ((<*>) . f) | ||
| 66 | |||
| 67 | instance (Val m b ~ m b, Ctx b ~ '[], Fin b ~ b) => Bindable m b where | ||
| 68 | bindE :: (Val m a -> Val m b) -> Expr m '[a] b | ||
| 69 | bindE = EPri . (EVal .) | ||
diff --git a/events/src/Events/Spec/Parse.hs b/events/src/Events/Spec/Parse.hs index 912a308..f3114f1 100644 --- a/events/src/Events/Spec/Parse.hs +++ b/events/src/Events/Spec/Parse.hs | |||
| @@ -18,7 +18,7 @@ import Events.Spec.Types | |||
| 18 | import Control.Monad.Catch (MonadThrow) | 18 | import Control.Monad.Catch (MonadThrow) |
| 19 | 19 | ||
| 20 | parse :: MonadThrow m => Consumer Text m (Spec m) | 20 | parse :: MonadThrow m => Consumer Text m (Spec m) |
| 21 | parse = sinkParser $ (tokenize >>= pSpec) <* endOfInput | 21 | parse = sinkParser $ pSpec <* endOfInput |
| 22 | 22 | ||
| 23 | pSpec :: Monad m => Parser (Spec m) | 23 | pSpec :: Monad m => Parser (Spec m) |
| 24 | pSpec = mzero | 24 | pSpec = mzero |
diff --git a/events/src/Events/Spec/Types.hs b/events/src/Events/Spec/Types.hs index 5216f46..c7fd058 100644 --- a/events/src/Events/Spec/Types.hs +++ b/events/src/Events/Spec/Types.hs | |||
| @@ -13,8 +13,11 @@ module Events.Spec.Types | |||
| 13 | 13 | ||
| 14 | import Events.Types | 14 | import Events.Types |
| 15 | 15 | ||
| 16 | -- | A functional language reminiscent of typed lambda calculus with monadic | ||
| 17 | -- side-effects and foreign primitives | ||
| 16 | data Expr :: (* -> *) -> [*] -> * -> * where | 18 | data Expr :: (* -> *) -> [*] -> * -> * where |
| 17 | ELit :: Val m a -> Expr m ctx a | 19 | EVal :: Val m a -> Expr m ctx a |
| 20 | EPri :: (Val m a -> Expr m ctx b) -> Expr m (a ': ctx) b | ||
| 18 | EVar :: Elem a ctx -> Expr m ctx a | 21 | EVar :: Elem a ctx -> Expr m ctx a |
| 19 | ELam :: Expr m (arg ': ctx) res -> Expr m ctx (arg -> res) | 22 | ELam :: Expr m (arg ': ctx) res -> Expr m ctx (arg -> res) |
| 20 | EApp :: Expr m ctx (arg -> a) -> Expr m ctx arg -> Expr m ctx a | 23 | EApp :: Expr m ctx (arg -> a) -> Expr m ctx arg -> Expr m ctx a |
| @@ -38,8 +41,8 @@ data Length :: [a] -> * where | |||
| 38 | LZ :: Length '[] | 41 | LZ :: Length '[] |
| 39 | LS :: Length xs -> Length (x ': xs) | 42 | LS :: Length xs -> Length (x ': xs) |
| 40 | 43 | ||
| 41 | type family (xs :: [a]) ++ (ys :: [a]) :: [a] | 44 | type family (xs :: [a]) ++ (ys :: [a]) :: [a] where |
| 42 | type instance '[] ++ ys = ys | 45 | '[] ++ ys = ys |
| 43 | type instance (x ': xs) ++ ys = x ': (xs ++ ys) | 46 | (x ': xs) ++ ys = x ': (xs ++ ys) |
| 44 | infixr 5 ++ | 47 | infixr 5 ++ |
| 45 | 48 | ||
