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)