module Lam where data E = Con Int | Var String | Ap E E | Lam String E data V = Num Int | Clos String E [(String,V)] eval e env = case e of Con n -> Num n Var s -> look s env Ap e1 e2 -> apply (eval e1 env) (eval e2 env) Lam x e1 -> Clos x e1 env apply f v = case f of Clos x e env -> eval e ((x,v):env) look x env = case env of nv:env' -> case nv of (n,v) -> if x==n then v else look x env'You may find it helpful to place the following initial call in a file:
eval (Lam "f" (Lam "x" (Ap (Var "f") (Ap (Var "f") (Var "x"))))) []Check that you can specialise the interpreter to this term. Since nothing is annotated as static, you should see no useful specialisation at this stage.
Now improve the specialisation of the interpreter in the following stages. Each stage involves adding annotations to the interpreter, but some also require rewriting parts of it to make the interpreter `more specialisable'.