[英]How can I do conditional monadic parsing using parsec?
想象一下下面的例子
data A = ...
data B = ...
data C = ...
convertA :: A -> C
parseA :: Parser A
parseB :: Parser B
parseC :: Parser C
parseC = do
a <- parseA
if parsed? a
then return $ convertA a
else parseB
有没有办法实现这样的逻辑,我可以尝试使用解析器,如果成功,对结果进行一些转换,否则使用另一个解析器? 我知道这个特殊的例子可以写成如下
parseC = (convertA <$> parseA) <|> parseB
但是有一种更通用的方式来表示这种模式的monadic符号吗?
你可以用monadically代表它,但我不知道我是否称它为更通用的模式。
通常,解析器的成功或失败是通过MonadPlus
和Alternative
接口隐式处理的。 但是,如果您真的想要,可以在Monad
上下文中重新确定成功/失败并对其进行操作。 执行该具体化的功能是optionMaybe
中的optionMaybe 。
parseC :: Parser C
parseC = do
ma <- optionMaybe parseA
case ma of
Just a -> return $ convertA a
Nothing -> parseB
这里一个重要的注意事项是optionMaybe
是......特别的。 它只是一个成功的Nothing
结果的情况下提供的解析器失败不消耗输入 。 当然,如果parseA
在失败时消耗输入,那么你的示例代码就会被破坏,所以我假设你熟悉这个问题。 这种破坏是我讨厌parsec并且永远不会在我自己的代码中使用它的原因。 对于编辑抱歉,我只是不认为这个问题是每个用户都应该被迫绊倒的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.