Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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 实现'Applicative Parser'的Apply函数_Parsing_Haskell - Fatal编程技术网

Parsing 实现'Applicative Parser'的Apply函数

Parsing 实现'Applicative Parser'的Apply函数,parsing,haskell,Parsing,Haskell,从Brent Yorgey的2013年Penn中,在获得定义a的帮助后,我尝试制作一个应用程序解析器: 以下是我的尝试: instance Applicative (Parser) where pure x = Parser $ \_ -> Just (x, []) (Parser f) <*> (Parser g) = case (\ys -> f ys) of Nothing -> Parser Nothi

从Brent Yorgey的2013年Penn中,在获得定义a的帮助后,我尝试制作一个应用程序解析器:

以下是我的尝试:

instance Applicative (Parser) where
  pure x                    = Parser $ \_ -> Just (x, [])
  (Parser f) <*> (Parser g) = case (\ys -> f ys) of Nothing      -> Parser Nothing
                                                    Just (_, xs) -> Parser $ g xs
但是,我在apply定义上遇到编译时错误

直觉上,我相信使用它可以实现功能性

如果我有一个foo解析器和一个bar解析器,那么我应该能够使用apply来表示:foo后跟bar。换句话说,foobar的输入应该成功匹配,而foobip则不会。它将在第二个解析器上失败

然而,我认为这些类型是:

解析器a->b->解析器a->解析器b

所以,这让我觉得我的直觉并不完全正确


请给我一个提示,指导我理解如何实现apply。

您的代码基于对解析器的误解。别担心,实际上每个人都会犯这个错误

newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
让我们详细分析一下这意味着什么

String -> Maybe (a, String)
[1]       [2]   [3] [4]
[1] :我拿了一根线,可能还回一根线

[2] :我可能无法将输入解析为所需的数据类型

[3] :我正在将字符串解析为的所需类型

[4] :已消耗解析数据所需的数据量后的剩余输入

解析器是文本输入的函数,可能是一个值的元组和文本的其余部分。解析器显然不是元组,否则就不会有解析器。只是元组中的数据

我不会告诉你如何实现,其他人也不应该,因为这会剥夺你的经验

但是,我将为您提供pure,以便您了解基本模式:

 pure a = Parser (\s -> Just (a, s))

看到了吗?这是s的函数->可能是a,s。我故意用我的术语来模仿类型变量,以使其更为明显。

您的代码是基于对解析器的误解。别担心,实际上每个人都会犯这个错误

newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
让我们详细分析一下这意味着什么

String -> Maybe (a, String)
[1]       [2]   [3] [4]
[1] :我拿了一根线,可能还回一根线

[2] :我可能无法将输入解析为所需的数据类型

[3] :我正在将字符串解析为的所需类型

[4] :已消耗解析数据所需的数据量后的剩余输入

解析器是文本输入的函数,可能是一个值的元组和文本的其余部分。解析器显然不是元组,否则就不会有解析器。只是元组中的数据

我不会告诉你如何实现,其他人也不应该,因为这会剥夺你的经验

但是,我将为您提供pure,以便您了解基本模式:

 pure a = Parser (\s -> Just (a, s))

看到了吗?这是s的函数->可能是a,s。我故意用我的术语来模拟类型变量,使其更为明显。

这里有一个引导性问题:如果p1将消耗一些输入并生成一个函数,而您需要应用该函数的结果,那么在您的代码中哪里可以找到该函数?你在哪里可以找到它的应用程序?你的类型是正确的。您需要解析器b,因此您应该返回与纯x形式相同的东西;您应该在开始时编写解析器$\s->。因为解析器f::Parser a->b有f::String->maybea->b,String,所以可以将f应用于字符串,得到一个可以进行模式匹配的字符串。如果这只是一个函数,remainingInput,那么你可以将g应用到remainingInput,得到类型可能是a,String的东西,如果你从中得到一个结果,比如aValue,最后,你可以将一些函数应用于aValue。这里有一个引导性问题:如果p1将使用一些输入并生成一个函数,而你需要应用该函数的结果,那么在你的代码中,你在哪里可以找到该函数?你在哪里可以找到它的应用程序?你的类型是正确的。您需要解析器b,因此您应该返回与纯x形式相同的东西;您应该在开始时编写解析器$\s->。因为解析器f::Parser a->b有f::String->maybea->b,String,所以可以将f应用于字符串,得到一个可以进行模式匹配的字符串。如果这只是一个函数,remainingInput,那么你可以将g应用到remainingInput,得到类型可能是a,String的东西,如果你从中得到一个结果,比如aValue,finalRemainingInput您可以将某些函数应用于aValue…。pure定义的关键区别在于,它所提供的输入与它返回的其余输入相同,因此它只保留输入流,而不是通过丢弃其余输入u并返回[]来终止解析运行作为剩余的输入…,pure定义的关键区别在于,它被赋予的输入与它返回的剩余输入相同,因此它只保留输入流,而不是通过丢弃剩余的输入u并返回[]作为剩余输入来终止解析运行。