Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 如何使用parsec进行条件单子解析?_Parsing_Haskell_Parsec - Fatal编程技术网

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