diff options
Diffstat (limited to 'events/src/Events/Spec/Eval.hs')
-rw-r--r-- | events/src/Events/Spec/Eval.hs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/events/src/Events/Spec/Eval.hs b/events/src/Events/Spec/Eval.hs new file mode 100644 index 0000000..3a23e0b --- /dev/null +++ b/events/src/Events/Spec/Eval.hs | |||
@@ -0,0 +1,38 @@ | |||
1 | {-# LANGUAGE GADTs, DataKinds, TypeOperators, RankNTypes, ScopedTypeVariables #-} | ||
2 | |||
3 | module Events.Spec.Eval | ||
4 | ( evalExpr | ||
5 | ) where | ||
6 | |||
7 | import Events.Spec.Types | ||
8 | |||
9 | shift :: forall m ts2 t x. Expr m ts2 x -> Expr m (t ': ts2) x | ||
10 | shift = shift' LZ | ||
11 | where | ||
12 | -- 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 | ||
14 | shift' _ (ELit x) = ELit x | ||
15 | shift' l (EVar v) = EVar $ shiftElem l v | ||
16 | shift' l (ELam b) = ELam $ shift' (LS l) b | ||
17 | shift' l (EApp f x) = EApp (shift' l f) (shift' l x) | ||
18 | |||
19 | shiftElem :: forall ts1 u. Length ts1 -> Elem u (ts1 ++ ts2) -> Elem u (ts1 ++ t ': ts2) | ||
20 | shiftElem LZ e = ES e | ||
21 | shiftElem (LS _) EZ = EZ | ||
22 | shiftElem (LS l) (ES e) = ES $ shiftElem l e | ||
23 | |||
24 | |||
25 | 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 | ||
27 | beta' _ _ (ELit x) = ELit x | ||
28 | beta' e LZ (EVar EZ ) = e | ||
29 | beta' _ LZ (EVar (ES v)) = EVar v | ||
30 | beta' _ (LS _) (EVar EZ ) = EVar EZ | ||
31 | beta' e (LS l) (EVar (ES v)) = shift $ beta' e l (EVar v) | ||
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) | ||
34 | |||
35 | evalExpr :: Expr m '[] t -> Val m t | ||
36 | evalExpr (ELit a) = a | ||
37 | evalExpr (ELam a) = a | ||
38 | evalExpr (EApp f a) = evalExpr $ beta a (evalExpr f) | ||