繁体   English   中英

如何使用parsec进行条件monadic解析?

[英]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代表它,但我不知道我是否称它为更通用的模式。

通常,解析器的成功或失败是通过MonadPlusAlternative接口隐式处理的。 但是,如果您真的想要,可以在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM