Search code examples
haskelluniplate

Count `Pat`s in a Module


I need to count the number of Pat in a haskell Module. I know the simplest way is to pattern match on each level of the AST, which will result in a huge function that looks like the entire AST. I believe there's some way to take advantage of typeclasses like Functor or the State Monad to lean on some existing function that walks the tree (like prettyPrint) and trace a counter along, but I'm not sure how it works exactly.


Solution

  • It's very easy using uniplate:

    import Data.Data
    import Data.Generics.Uniplate.Data
    import Control.Monad
    import Language.Haskell.Exts
    
    findPats :: Data a => a -> [Pat]
    findPats = universeBi
    
    test = do
      content <- readFile "Simple.hs"
      case parseModule content of
        ParseFailed _ e -> error e
        ParseOk a       -> do
          forM_ (findPats a) $ \p -> do
            putStrLn $ "got a pat: " ++ show p
    

    Essentially it's just the universeBi function.