zip AST与bool列表

时间:2015-08-02 19:23:09

标签: haskell uniplate

我有一个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个地方

1 个答案:

答案 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"