haskell - Is it possible to showcase the different strategies of evaluation by modifying this simple reducer? -
i kind prefers learning looking @ code instead of reading long explanations. might 1 of reasons dislike long academic papers. code unambiguous, compact, noise-free , if don't can play - no need ask author.
this complete definition of lambda calculus:
-- lambda calculus term function, application or variable. data term = lam term | app term term | var int deriving (show,eq,ord) -- reduces lambda term normal form. reduce :: term -> term reduce (var index) = var index reduce (lam body) = lam (reduce body) reduce (app left right) = case reduce left of lam body -> reduce (substitute (reduce right) body) otherwise -> app (reduce left) (reduce right) -- replaces bound variables of `target` `term` , adjusts bruijn indices. -- don't mind variables, keep track of bruijn indices. substitute :: term -> term -> term substitute term target = go term true 0 (-1) target go t s d w (app b) = app (go t s d w a) (go t s d w b) go t s d w (lam a) = lam (go t s (d+1) w a) go t s d w (var a) | s && == d = go (var 0) false (-1) d t go t s d w (var a) | otherwise = var (a + (if > d w else 0)) -- if evaluator correct, test should print church number #4. main = let 2 = (lam (lam (app (var 1) (app (var 1) (var 0))))) print $ reduce (app 2 two)
in opinion, "reduce" function above says more lambda calculus pages of explanations , wish @ when started learning. can see implements strict evaluation strategy goes inside abstractions. on spirit, how code modified in order illustrate many different evaluation strategies lc can have (call-by-name, lazy evaluation, call-by-value, call-by-sharing, partial evaluation , on)?
call-by-name requires few changes:
not evaluating body of lambda abstraction:
reduce (lam body) = (lam body)
.not evaluating argument of application. instead, should substitute is:
reduce (app left right) = case reduce left of lam body -> reduce (substitute right body)
call-by-need(aka lazy evaluation) seems harder(or maybe impossible) implement in declarative manner because need memoize values of expressions. not see way achieve minor changes.
call by-sharing not applicable simple lambda calculus because not have objects , assignments here.
we use full beta reduction, need chose deterministic order of evaluation(we cannot pick "arbitrary" redex , reduce using code have now). choice yield evaluation strategy(possible 1 of described above).
Comments
Post a Comment