计算模块中的“Pat”

Count `Pat`s in a Module

我需要统计Pat in a haskell Module的数量。我知道最简单的方法是在 AST 的每个级别上进行模式匹配,这将产生一个看起来像整个 AST 的巨大函数。我相信有一些方法可以利用像 FunctorState Monad 这样的类型类来依赖一些遍历树的现有函数(比如 prettyPrint)并跟踪一个计数器,但是我'我不确定它是如何工作的。

使用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

本质上就是universeBi函数。