data
type is factored out by the introduction of a separate type which explicitly represents the different variants within the original type.
data Expr
= Lit Integer | -- Literal integer value
Vbl Var | -- Assignable variables
Add Expr Expr | -- Expression addition: e1+e2
Assign Var Expr -- Assignment: x:=e
type Var = String
type Store = [ (Var, Integer) ]
lookup :: Store -> Var -> Integer
lookup st x = head [ i | (y,i) <- st, y==x ]
update :: Store -> Var -> Integer -> Store
update st x n = (x,n):st
eval :: Expr -> Store -> (Integer, Store)
eval (Lit n) st
= (n,st)
eval (Vbl x) st
= (lookup st x,st)
eval (Add e1 e2) st
= (v1+v2, st2)
where
(v1,st1) = eval e1 st
(v2,st2) = eval e2 st1
eval (Assign x e) st
= (v, update st' x v)
where
(v,st') = eval e st
|
data Expr
= Lit Integer |
Vbl Var |
Add Expr Expr |
Assign Var Expr
type Var = String
type Store = [ (Var, Integer) ]
lookup :: Store -> Var -> Integer
lookup st x = head [ i | (y,i) <- st, y==x ]
update :: Store -> Var -> Integer -> Store
update st x n = (x,n):st
evalST :: Expr -> State Store Integer
evalST (Lit n)
= do
return n
evalST (Vbl x)
= do
st <- get
return (lookup st x)
evalST (Add e1 e2)
= do
v1 <- evalST e1
v2 <- evalST e2
return (v1+v2)
evalST (Assign x e)
= do
v <- evalST e
st <- get
put (update st x v)
return v
|
General comment:
This refactoring introduces a particular instance of the Monad
class, based on uses of the instance functions. Other monadifications will introduce use of a general monad into non-monadic code (i.e. code which uses the identity monad).
Left to right comment:
The code on the LHS explicitly threads the state through the computation. Since such a form of computation is represented by the |
Right to left comment:
Moving from RHS to LHS makes the state manipulation explicit; this might precede further modifications. |
Left to right conditions:
There is no condition on this. |
Right to left conditions:
There is no restriction on the right to left transition. |