module Fun where { import FunParser; import FunType; {---------------------------------------------------------------------- インタプリタ(関数) * Var + * 関数の導入 Expr -> Expr * Expr | Expr + Expr | Expr Expr | Const | ( Expr ) | Ident | let Ident = Expr in Expr | \ Ident -> Expr ----------------------------------------------------------------------} type Env = [(String, Value)]; -- lookup' :: Eq a => a -> [(a, b)] -> b; lookup' :: String -> [(String, a)] -> a; lookup' x ((n,v):rest) = if n==x then v else lookup' x rest; {- -- Monadic Version interp :: Expr -> Env -> M Value; interp (Const c) e = unitM c; interp (Add m n) e = interp m e `bindM` \ (Num c) -> interp n e `bindM` \ (Num d) -> unitM (Num (c+d)); interp (Mult m n) e = interp m e `bindM` \ (Num c) -> interp n e `bindM` \ (Num d) -> unitM (Num (c*d)); interp (Var x) e = unitM (lookup' x e); interp (Let (x, m) n) e = interp m e `bindM` \ v -> interp n ((e,x):v); interp (App f x) e = interp f e `bindM` \ g -> case g of { Fun h -> interp x e `bindM` \ y -> h y; {- _ -> failM "Function expected" -} }; interp (Lambda x m) e = unitM (Fun (\ v -> interp m ((e,x):v))); -} -- Non-Monadic Version interp :: Expr -> Env -> Value; interp (Const c) e = c; interp (Add m n) e = let { Num c = interp m e; Num d = interp n e } in Num (c+d); interp (Mult m n) e = let { Num c = interp m e; Num d = interp n e } in Num (c*d); interp (Var x) e = lookup' x e; interp (Let (x, m) n) e = let { v = interp m e } in interp n ((x,v):e); interp (App f x) e = case interp f e of { Fun g -> g (interp x e) {- _ -> Str "error: Function expected" -} }; interp (Lambda x m) e = Fun (\ v -> interp m ((x,v):e)); run :: String -> String; run str = showValue (interp (myParse str) []); main :: IO (); main = interact run; load :: String -> IO (); load path = readFile path >>= \ prog -> putStrLn (run prog); -- for example -- run "let sq = \\ x -> x*x in sq (sq 2)" }