type term = Var of int | Lambda of term | App of term * term | Constant of int | Primitive of primitive * term list and value = Int of int | Closure of term * environment and environment = value list and primitive = value list -> value let rec eval env term = match term with Var n -> List.nth env n | Lambda a -> Closure(a, env) | App(a, b) -> let (Closure(c, envp)) = eval env a in let v = eval env b in eval (v :: envp) c | Constant n -> Int n | Primitive(p, arguments) -> p (List.map (eval env) arguments)