On Fri, Jun 29, 2007 at 07:18:00PM +0100, Andrew Coppin wrote: > Dan Mead wrote: > >Andrew: Try using catchalls in your guards > > > > > >pattern1 > >| guard1 = > >| guard2 = > >| otherwise = > > > >This makes it much easier to use pattern guards. > >"otherwise" is a reserved word used for this stuff in ghc. > > Yeah, it's good practice to include an explicit otherwise clause - but > in this specific instance, I'm trying to do tricky stuff where one rule > falls through to another if some condition doesn't hold - but that > condition is only expressible as a function. > > Well, let me show you the code - somebody will probably recognise this > stuff... > > convert1 :: Expression -> Expression > convert1 S = S > convert1 K = K > convert1 I = I > convert1 (Var v) = Var v > convert1 (x :@: y) = (convert1 x) :@: (convert1 y) > convert1 (Lam n e) > | n `not_in` e = K :@: (convert1 e) > convert1 (Lam n (Var v)) > | n == v = I > | otherwise = K :@: (convert1 (Var v)) > convert1 (Lam n (x :@: y)) > | y `is_var` n && n `not_in` x = convert1 x > | otherwise = S :@: (convert1 (Lam n x)) :@: > (convert1 (Lam n y)) > convert1 (Lam n (Lam m e)) > | n `not_in` e = K :@: (convert1 (Lam m e)) > | otherwise = convert1 (Lam n (convert1 (Lam m e)))
This is *much* easier expressed as a bottom-up traversal. compile = transform optimize . transform eliminate eliminate (Lam v e) = transform (abstract v) e eliminate x = x abstract v (Var v') | v == v' = I abstract v (a :@ b) = S :@ a :@ b abstract v x = x optimize (S :@ (K :@ x) :@ (K :@ y)) = K :@ (x :@ y) optimize (S :@ (K :@ x) :@ I) = x optimize x = x (Here using Uniplate, mostly because it is the freshest in my mind of all of them). Stefan _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe