The interpeter evaluates an Expression with respect to an Environment, which is a list of bindings of Names to Values. The only kinds of Values are Numbers, Functions, and Errors.
interp :: Expr -> Env -> Val type Name = String type Env = [(Name,Val)] -- kinds of expression data Expr = Con Int -- integer constant | Var Name -- variable | Lam Name Expr -- lambda expression | Add Expr Expr -- sum of two values | App Expr Expr -- apply one value to another -- kinds of value data Val = Num Int | Fun (Val->Val) | Err -- how to print a value instance Show Val where show (Num x) = show x show (Fun _) = "<function>" show Err = "<bad>" -- interpreter proper -- e environment -- v value -- x,y integer -- s string -- f Haskell function -- t,u expression interp (Con x) e = Num x interp (Var s) e = case lookup s e of Just v -> v Nothing -> Err interp (Lam s u) e = Fun (\v->interp u ((s,v):e)) interp (Add t u) e = case (interp t e, interp u e) of (Num x, Num y) -> Num (x+y) _ -> Err interp (App t u) e = case (interp t e, interp u e) of (Fun f, v) -> f v _ -> Err interp _ e = Err test t = interp t [] test1 = test (Con 0) test2 = test (App (Lam "x" (Add (Con 1) (Var "x"))) (Con 2))
let fact = \n->if n==0 then 1 else n*fact(n-1)
parse :: String -> Exprto create Expressions from strings in a more readable language. The language should be recursively defined, using parentheses for grouping.
data Ohm = Ohm Doublecreate workable definitions for + and *, and arrange that the result of executing
r1 = Ohm 1 r3 = Ohm 3 main = [r1*r1, r1+r1, r1+r3, r1*(r3+r3+r3)]prints as [2.0, 0.5, 0.75, 2.0]