带布尔列表的压缩 AST

zip AST with bool list

我在 order.For 示例中有一个 AST representing a haskell program and a bitvector/bool list representing the presence of strictness annotations on Patterns,1000 表示具有 4 Pats 的程序,其中第一个是 BangPat。有什么方法可以根据列表打开和关闭 AST 中的注释吗?

-- 编辑:进一步阐明我想要editBang做什么

根据user5042的回答: Simple.hs :=

main = do
  case args of
    [] -> error "blah"
    [!x] -> putStrLn "one"
    (!x : xs) -> putStrLn "many"

我想要editBang "Simple.hs" [True, True, True, True]生产

main = do
  case args of
    [] -> error "blah"
    [!x] -> putStrLn "one"
    (!(!x : !xs)) -> putStrLn "many"

以上是!可以出现的4个地方

作为第一步,这里是如何使用 transformBi:

import Data.Data
import Control.Monad
import Data.Generics.Uniplate.Data
import Language.Haskell.Exts
import Text.Show.Pretty (ppShow)

changeNames x = transformBi change x
  where change (Ident str) = Ident ("foo_" ++ str)
        change x           = x

test2 = do
  content <- readFile "Simple.hs"
  case parseModule content of
    ParseFailed _ e -> error e
    ParseOk a       -> do
      let a' = changeNames a
      putStrLn $ ppShow a'

changeNames 函数查找所有出现的 Ident s 并将其替换为源代码树中的 Ident ("foo_"++s)

有一个名为 transformBiM 的 monadic 版本,它允许替换函数是 monadic,这将允许您在发现 bang 模式时使用 Bools 列表中的元素。

这是一个完整的工作示例:

import Control.Monad
import Data.Generics.Uniplate.Data
import Language.Haskell.Exts
import Text.Show.Pretty (ppShow)
import Control.Monad.State.Strict

parseHaskell path = do
  content <- readFile path
  let mode = ParseMode path Haskell2010 [EnableExtension BangPatterns] False False Nothing
  case parseModuleWithMode mode content of
    ParseFailed _ e -> error $ path ++ ": " ++ e
    ParseOk a       -> return a

changeBangs bools x = runState (transformBiM go x) bools
  where go pp@(PBangPat p) = do
           (b:bs) <- get
           put bs
           if b
             then return p
             else return pp
        go x = return x

test = do
  a <- parseHaskell "Simple.hs"
  putStrLn $ unlines . map ("before: " ++) . lines $ ppShow a
  let a' = changeBangs [True,False] a
  putStrLn $ unlines . map ("after : " ++) . lines $ ppShow a'

您也可以考虑使用 rewriteBiM

文件Simple.hs:

main = do
  case args of
    [] -> error "blah"
    [!x] -> putStrLn "one"
    (!x : xs) -> putStrLn "many"