Jak*_*old 3 parsing haskell 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
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这样的逻辑,我可以尝试使用解析器,如果成功,对结果进行一些转换,否则使用另一个解析器?我知道这个特殊的例子可以写成如下
parseC = (convertA <$> parseA) <|> parseB
Run Code Online (Sandbox Code Playgroud)
但是有一种更通用的方式来表示这种模式的monadic符号吗?
你可以用monadically代表它,但我不知道我是否称它为更通用的模式.
通常,解析器的成功或失败是通过MonadPlus和Alternative接口隐式处理的.但是,Monad如果您真的想要,可以在上下文中重新确定成功/失败并对其进行操作.执行该具体化的功能optionMaybe在Text.Parsec.Combinator中.
parseC :: Parser C
parseC = do
ma <- optionMaybe parseA
case ma of
Just a -> return $ convertA a
Nothing -> parseB
Run Code Online (Sandbox Code Playgroud)
这里有一个重要的注意事项optionMaybe是..特别的.只有Nothing在提供给它的解析器失败而不消耗输入的情况下,它才会成功.当然,如果parseA在失败时消耗输入,你的示例代码仍会被破坏,所以我假设你已经熟悉了这个问题.这种破坏是我讨厌parsec并且永远不会在我自己的代码中使用它的原因.对于编辑抱歉,我只是不认为这个问题是每个用户都应该被迫绊倒的问题.
| 归档时间: |
|
| 查看次数: |
340 次 |
| 最近记录: |