I'm in the middle of writing a program for transforming haskell modules, a large amount of which is essentially renaming the HsNames inside. It is *almost* sufficient for me to simply write a function: transformName :: HsName -> QM HsName (QM is the monad I'm living in at the moment) and then simply apply a gmapM to the HsModule. The problem is that "almost" referenced above. Specifically, I need to do something special when I reach an HsFunBind in the source (basically, just push the local definitions into an environment held in the QM monad and then pop them back out when we leave). I have a feeling such a thing should be possible, but I haven't yet figured out how. My first attempt was essentially to try to do some sort of dispatch function using the gmap library. To simplify, consider: newtype Name = Name String deriving (Eq, Ord, Show) data Foo = Foo Name [Foo] | Bar Name deriving (Eq, Ord, Show) testFoo = Foo (Name "a") [Foo (Name "b") [Bar (Name "c"), Bar (Name "d"), Foo (Name "e") [Bar (Name "f")], Bar (Name "g")], Bar (Name "h")] with the obvious instance declarations of Term and Typeable. Now, we want a function which will replace every 'Name s' with 'Name (s++s)' and, when we reach a 'Foo s', we want to print ">s" onenter and "<s" on exit. we can do the first one with: doubleName :: Name -> IO Name doubleName (Name s) = return (Name (s++s)) everywhereM (mkM doubleName) testFoo which runs fine and produces the correct results. As for the printing, I want something like: flagFoo x | x "is a Name" = doubleName x | x "is a Foo s l" = do putStrLn ('>':s) recurse on s and l putStrLn ('<':s) | otherwier = gmapM flagFoo x or something like that. obviously I could do this by writing the recursion myself, but i'm trying to get around that. even if i could write something like: doName = doubleName doFoo x@(Foo s l) = do putStrLn ...; something x; putStrLn ... doFoo x = something x and then domsehting like: everywhereM (doName .|. doFoo) testFoo then that woudl be fine. I just don't want to have to write out all the other cases for doFoo that I don't care about, because for the real HsDecl, this is a *lot* of junk. Anyone know how to solve this problem? -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume