Text.Regex.Applicative - 多行注释

时间:2018-02-15 09:10:35

标签: regex haskell applicative parser-combinators

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

regex = pure (++) <$> string "/*" <*> many (anySym) <*> string "*/"
match regex "/* hello world */"

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

1 个答案:

答案 0 :(得分:4)

你正在混淆适用的习语。它是

f <$> x <*> y <*> z
  ^^^

pure f <*> x <*> y <*> z
       ^^^

您选择的混合物

pure f <$> x <*> y <*> z

具有误导性。因为

(<$>) :: (Functor f) => (a -> b) -> f a -> f b

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

const (++) <$> string "/*" <*> many anySym <*> string "/*"

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

您无法将(++)应用于三个参数,这就是其他表单无法编译的原因。我认为你真正需要的是

sequenceA :: (Applicative f) => [f a] -> f [a]

将解析器的列表*转换为提供列表的解析器,然后concat结果。

regex = concat <$> sequenceA [string "/*", many anySym, string "*/"]

* 实际上sequenceA更为通用,类型为(Applicative f, Traversable t) => t (f a) -> f (t a),但我并不想在这个答案中走得太远。