Parsing 如何使用parsec进行条件单子解析?
想象一下下面的例子Parsing 如何使用parsec进行条件单子解析?,parsing,haskell,parsec,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 数据A=。。。 数据B=。。。 数据C=。。。 conve
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
数据A=。。。
数据B=。。。
数据C=。。。
convertA::A->C
解析器A::解析器A
解析器B::解析器B
解析器C::解析器C
parseC=do
a你可以用更单一的方式来表示它,但我不知道我是否可以称之为更一般的模式
通常,解析器的成功或失败是通过MonadPlus
和Alternative
接口隐式处理的。但是,如果您确实愿意,您可以具体化成功/失败,并在Monad
上下文中对其进行操作。实现具体化的功能是中的optionMaybe
parseC::Parser C
parseC=do
ma返回$convertA
无->解析B
这里需要注意的一点是,optionMaybe
is。。特别的。只有当提供给它的解析器在不使用输入的情况下失败时,它才会在Nothing
结果的情况下成功。当然,如果parseA
在失败时可以使用输入,那么您的示例代码无论如何都会被破坏,所以我假设您熟悉这个问题。顺便说一句,这就是为什么我讨厌parsec,并且永远不会在我自己的代码中使用它。很抱歉发表社论,我只是不认为每个用户都应该被这个问题所困扰。出于好奇,你希望一个未损坏的解析器做什么?隐式尝试
一切?感谢您的解释,最后我做了try(convertA parseA)parseB
。是否尝试与选项一起工作可能是
?另外,您使用什么来代替parsec?:)@JakubArnold是的,try
可以与选项maybe
配合使用@另一个真正的可组合解析器,我喜欢你从uu parsinglib
中得到的东西,这很像在任何地方都有一个隐式的try
,尽管它比这聪明一点。对于高效的解析器,我只需要使用attoparsec
。它有着与parsec类似的问题,但至少在整个过程中都明确涉及性能。
parseC = (convertA <$> parseA) <|> parseB
parseC :: Parser C
parseC = do
ma <- optionMaybe parseA
case ma of
Just a -> return $ convertA a
Nothing -> parseB