Text.Regex.Applicative-多行注释

20X*_*0XX 3 regex haskell parser-combinators applicative

我无法弄清楚使用Haskell regex-applicative软件包使用该replace功能对多行注释执行替换的正确方法。首先,我试图match返回正确的字符串作为测试:

regex = pure (++) <$> string "/*" <*> many (anySym) <*> string "*/"
match regex "/* hello world */"
Run Code Online (Sandbox Code Playgroud)

哪个返回hello world */。我不明白为什么第一个匹配部分被切除。有任何想法吗?

luq*_*qui 5

您正在混淆应用习语。要么

f <$> x <*> y <*> z
  ^^^
Run Code Online (Sandbox Code Playgroud)

要么

pure f <*> x <*> y <*> z
       ^^^
Run Code Online (Sandbox Code Playgroud)

您选择的混合物

pure f <$> x <*> y <*> z
Run Code Online (Sandbox Code Playgroud)

有误导性。因为

(<$>) :: (Functor f) => (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

将函数作为其左参数,pure f(->) r应用程序中进行解释,其中pure = const。所以你得到

const (++) <$> string "/*" <*> many anySym <*> string "/*"
Run Code Online (Sandbox Code Playgroud)

现在我们可以希望看到为什么忽略第一个字符串。

您不能将其应用于(++)三个参数,这就是为什么其他形式无法编译的原因。我认为您真正需要的是

sequenceA :: (Applicative f) => [f a] -> f [a]
Run Code Online (Sandbox Code Playgroud)

它将解析器列表*转换为给出列表和concat结果的解析器。

regex = concat <$> sequenceA [string "/*", many anySym, string "*/"]
Run Code Online (Sandbox Code Playgroud)

*实际上sequenceA,使用type更为笼统,(Applicative f, Traversable t) => t (f a) -> f (t a)但是我不想在这个问题上走得太远。