我有一个AST
代表一个haskell程序和一个bitvector / bool列表,表示Pattern
s依次存在严格注释。例如,Pat
表示一个程序有4个BangPat
,其中第一个是AST
。有没有办法可以根据列表打开和关闭editBang
中的注释?
- 编辑:进一步澄清我想要Simple.hs :=
做什么
根据user5042的回答:
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"
能够制作
!
鉴于以上是my-datepicker
可以出现的唯一4个地方
答案 0 :(得分:3)
作为第一步,这是如何使用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,这样你就可以在你发现爆炸模式时使用Bool列表中的元素。
这是一个完整的工作示例:
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"