,(['_add'], binop \(Int i) (Int j)->Int (i + j))
,(['_mul'], binop \(Int i) (Int j)->Int (i * j))
,(['_div'], binop \(Int i) (Int j)->Int (i / j))
+ ,(['_fst'], Builtin \t->eval t >>= \(a ** b)->pure a)
+ ,(['_snd'], Builtin \t->eval t >>= \(a ** b)->pure b)
]
where
binop :: (Value Value -> Value) -> Value
eval (Lit v) = pure v
eval (Var v) = gets (lookup v) >>= maybe (liftT (Left [toString v +++ " not found"])) pure
eval (Lambda a b) = pure (Lambda` a b)
+eval (Tuple a b) = pure (a ** b)
eval (App e1 e2) = eval e1 >>= \v->case v of
(Lambda` v b) = eval (sub v e2 b)
(Builtin f) = f e2 >>= eval