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