gpt4 book ai didi

parsing - 如何使用秒差距进行条件单子(monad)解析?

转载 作者:行者123 更新时间:2023-12-02 13:45:57 27 4
gpt4 key购买 nike

想象一下下面的例子

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

但是有没有更通用的方法来用一元表示法表示这种模式?

最佳答案

您可以更单一地表示它,但我不知道是否可以将其称为更通用的模式。

通常,解析器的成功或失败是通过 MonadPlusAlternative 接口(interface)隐式处理的。但是,如果您确实愿意,可以具体化成功/失败并在 Monad 上下文中对其进行操作。执行具体化的函数是 Text.Parsec.Combinator 中的 optionMaybe .

parseC :: Parser C
parseC = do
ma <- optionMaybe parseA
case ma of
Just a -> return $ convertA a
Nothing -> parseB

这里的一个重要注意事项是 optionMaybe 是..特殊的。只有在提供给它的解析器在不消耗输入的情况下失败的情况下,它才会成功并获得Nothing结果。当然,如果 parseA 可以在失败时消耗输入,那么您的示例代码无论如何都会被破坏,所以我假设您熟悉这个问题。顺便说一句,这种破坏就是我讨厌秒差距并且永远不会在我自己的代码中使用它的原因。抱歉进行社论,我只是认为这个问题不应该是每个用户都应该被迫遇到的问题。

关于parsing - 如何使用秒差距进行条件单子(monad)解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25189309/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com