This is one of the problems with which the common style libraries “Breaking your boilers” shine!
I am most familiar with the uniplate package , but I have not actually installed it, so I will use the (very similar) functions found in the lens package . The idea here is that it uses Data.Data.Data (which is the best qualified name ever) and related classes to perform common operations in a polymorphic way.
Here is the simplest possible example:
alphaConvert :: Module -> Module alphaConvert = template %~ changeName changeName :: Name -> Name changeName (Ident n) = Ident $ n ++ "_conv" changeName n = n
The (%~) operator from lens simply means applying the changeName function to everything selected by the general template changeName . So what is it like to find each alphanumeric identifier and add _conv to it. Running this program from its own source creates the following:
module AlphaConv where import Language.Haskell.Exts import Control.Lens import Control.Lens.Plated import Data.Data.Lens instance Plated_conv Module_conv main_conv = do ParseOk_conv md_conv <- parseFile_conv "AlphaConv.hs" putStrLn_conv $ prettyPrint_conv md_conv let md'_conv = alphaConvert_conv md_conv putStrLn_conv $ prettyPrint_conv md'_conv alphaConvert_conv :: Module_conv -> Module_conv alphaConvert_conv = template_conv %~ changeName_conv changeName_conv :: Name_conv -> Name_conv changeName_conv (Ident_conv n_conv) = Ident_conv $ n_conv ++ "_conv" changeName_conv n_conv = n_conv
Not very useful, because it does not distinguish between locally bound identifiers and those defined in the external area (for example, imported), but it demonstrates the main idea.
lens may seem a little intimidating (it has a lot more functionality than just that); you may find uniplate or another library more accessible.
The way you approach your real problem will be a multi-part conversion that first selects the subexpressions that you want to convert to the alpha transform inside, and then uses the transform for those that change the names you want to change.
source share