type exp = Var of int | Lit of int | Lam of (int * exp) | App of (exp * exp) | Plus of (exp * exp) | Minus of (exp * exp) | Ifz of (exp * exp * exp) and result = Resint of int | Closure of (int * exp * env) and env = Empty | Extended of (int * result * env) ;; (* >>>>>> This definition must remain intact <<<<<<< *) let sum10 = App(Lam(19, App(App(Var 19, Var 19), Lit 10)), Lam(18, Lam(17, Ifz(Var 17, Lit 0, Plus(Var 17, App(App(Var 18, Var 18), Minus(Var 17, Lit 1))))))) ;; exception Bad ;; let rec lookup(var, env) = match env with Empty -> raise Bad | Extended(v, r, next_env) -> if v = var then r else lookup(var, next_env) ;; let domath(op, r1, r2) = match (r1, r2) with (Resint n1, Resint n2) -> Resint(op(n1, n2)) | _ -> raise Bad ;; let rec eval(x, e) = match x with Var v -> lookup(v, e) | Lit i -> Resint i | Lam(var, body) -> Closure(var, body, e) | App(func, arg) -> let funval = eval(func, e) in let argval = eval(arg, e) in (match funval with Resint _ -> raise Bad | Closure(var, body, env) -> eval(body, Extended(var, argval, env))) | Plus(e1, e2) -> domath((fun(x,y) -> x + y), eval(e1, e), eval(e2, e)) | Minus(e1, e2) -> domath((fun(x,y) -> x - y), eval(e1, e), eval(e2, e)) | Ifz(test, zero, notzero) -> (match eval(test, e) with Resint 0 -> eval(zero, e) | _ -> eval(notzero, e)) ;; eval (sum10, Empty) ;;