module InterpA where -- The interpreter monad -- (Generated by MonadLab) import InterpMonadA -- Language syntax type Name = String data Term = Var Name | Con Int | Add Term Term | Lam Name Term | App Term Term mkfun :: Name -> M V -> M V mkfun x phi = rdEnvM >>= \ e -> return (Fun $ \ arg -> inEnvM ((x,arg):e) phi) appEnv :: Name -> M V appEnv x = rdEnvM >>= \ e -> case lookup x e of Nothing -> return Wrong (Just v) -> return v apply :: V -> V -> M V apply (Fun k) a = k a apply _ _ = return Wrong -- The interpreter add :: V -> V -> M V add (Num i) (Num j) = return (Num (i+j)) add _ _ = return Wrong interp :: Term -> M V interp (Var x) = appEnv x interp (Con i) = return (Num i) interp (Add u v) = interp u >>= \ a -> interp v >>= \ b -> add a b interp (Lam x v) = mkfun x (interp v) interp (App t u) = interp t >>= \ f -> interp u >>= \ a -> apply f a test :: Term -> V test t = runM (interp t) initEnv where initEnv = []