module BetaReduce where import HasBaseStruct(hsApp,hsLambda,hsEVar,hsParen) import Substitute(subst,mapExp) import HsExpStruct import HsExpUtil(exposeE) import HsPatUtil(isPVar) import Maybe(fromMaybe)
Find outermost beta redexes and reduce them. Beta redexes are expressions of the form
(\ x1 ... xn -> e) e1 ... en.
Pattern matching is not implemented.
beta e =
case isLambda fun of
Just (ps, body) -> substArgs [] ps args body
_ -> mapExp beta e
where
(fun,args) = flatApp e []
substArgs s (p:ps) (arg:args) body =
case isPVar p of
Just x -> substArgs ((x,arg):s) ps args body
_ -> keep s (p:ps) (arg:args) body
substArgs s ps args body = keep s ps args body
keep s ps args body = pApps (hsLambda' ps (subst f body)) args
where f y = fromMaybe (hsEVar y) (lookup y s)
flatApp e args =
case exposeE e of
Just (HsApp fun arg) -> flatApp fun (arg:args)
--Just (HsInfixApp e1 i e2) -> can not be a beta redex
_ -> (e,args)
pApps fun [] = fun
pApps fun args = apps (hsParen fun) args
apps fun [] = fun
apps fun (arg:args) = apps (hsApp fun arg) args
isLambda e =
case exposeE e of
Just (HsLambda ps body) -> Just (ps,body)
_ -> Nothing
-- Don't create arity 0 lambda asbtractions.
hsLambda' [] e = e
hsLambda' ps e = hsLambda ps e