25.10.2015 Views

Write You a Haskell Stephen Diehl

1kEcQTb

1kEcQTb

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

data Expr<br />

= Var Int<br />

| Lam Expr<br />

| App Expr Expr<br />

| Lit Int<br />

| Prim PrimOp Expr Expr<br />

deriving Show<br />

data PrimOp = Add | Mul<br />

deriving Show<br />

data Value<br />

= VInt Int<br />

| VClosure Expr Env<br />

deriving Show<br />

type Env = [Value]<br />

emptyEnv :: Env<br />

emptyEnv = []<br />

e evaluator function simply maps the local scope and a term to the final value. Whenever a variable is<br />

referred to it is looked up in the environment. Whenever a lambda is entered it extends the environment<br />

with the local scope of the closure.<br />

eval :: Env -> Expr -> Value<br />

eval env term = case term of<br />

Var n -> env !! n<br />

Lam a -> VClosure a env<br />

App a b -><br />

let VClosure c env’ = eval env a in<br />

let v = eval env b in<br />

eval (v : env’) c<br />

Lit n -> VInt n<br />

Prim p a b -> (evalPrim p) (eval env a) (eval env b)<br />

evalPrim :: PrimOp -> Value -> Value -> Value<br />

evalPrim Add (VInt a) (VInt b) = VInt (a + b)<br />

evalPrim Mul (VInt a) (VInt b) = VInt (a * b)<br />

Call-by-name<br />

In call-by-name evaluation, the arguments to lambda expressions are substituted as is, evaluation simply<br />

proceeds from left to right substituting the outermost lambda or reducing a value. If a substituted<br />

expression is not used it is never evaluated.<br />

70

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!