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.
Asked
Active
Viewed 68 times
2
-
Suppose you get to a `PInfixApp pat1 qname pat2`... do you want to recurse into `pat1` and `pat2` or just stop? – ErikR Aug 02 '15 at 19:12
-
They have [`Data`](https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Data.html#t:Data) instances, so you could use generics. – luqui Aug 02 '15 at 19:15
-
@user5402 I want to recurse – rem Aug 02 '15 at 19:16
-
@luqui can you elaborate? – rem Aug 02 '15 at 19:16
-
3@rem, it will take a bit of learning. The [paper](http://research.microsoft.com/en-us/um/people/simonpj/papers/hmap/) (the 2003 one, at the bottom) is pretty good and easy to read. – luqui Aug 02 '15 at 19:20
1 Answers
6
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.

ErikR
- 51,541
- 9
- 73
- 124