diff options
| -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 | ||
