1 implementation module int
8 import Control.Applicative
10 import Control.Monad.State
11 import Control.Monad.Trans
15 :: Eval a :== StateT EvalState (Either [String]) a
16 :: EvalState :== [([Char], Value)]
18 int :: Expression -> Either [String] Value
19 int e = evalStateT (eval e) preamble
22 [(['_if'], Func \i->pure (Func \t->pure (Func \e->eval i >>= \(Bool b)->if b (eval t) (eval e))))
23 ,(['_eq'], binop \(Int i) (Int j)->Bool (i==j))
24 ,(['_sub'], binop \(Int i) (Int j)->Int (i-j))
25 ,(['_add'], binop \(Int i) (Int j)->Int (i+j))
26 ,(['_mul'], binop \(Int i) (Int j)->Int (i*j))
27 ,(['_div'], binop \(Int i) (Int j)->Int (i/j))
30 binop op = Func \l->pure (Func \r->op <$> eval l <*> eval r)
32 sub :: [Char] Expression Expression -> Expression
33 sub ident subst (Let v b rest) = Let v (sub ident subst b) (if (v == ident) rest (sub ident subst rest))
34 sub ident subst (Var v)
36 sub ident subst (App e1 e2) = App (sub ident subst e1) (sub ident subst e2)
37 sub ident subst (Lambda v b)
38 | ident <> v = Lambda v (sub ident b subst)
41 eval :: Expression -> Eval Value
42 eval (Let ident body rest) = eval body >>= \v->modify (\vs->[(ident, v):vs]) >>| eval rest
44 eval (Var v) = gets (lookup v) >>= maybe (liftT (Left [toString v +++ " not found"])) pure
45 eval (App e1 e2) = eval e1 >>= \(Func v)->v e2
46 eval (Lambda a b) = pure (Func \arg->eval (sub a arg b))