型 所以它“合并”了两个Applicative f => f a,通过使用const,它将接受第一个项,而不是第二个。 因此,它先使用左操作数,然后使用右操作数,并返回第一个操作数的结果。 因此,在ReadP的上下文中,它将运行左边的解析器,然后是右边的解析器,然后忽略右边解析器的结果并返回第一个解析器。 举例来说:
get <* get
型 它将读取 * 两个 * 字符,并返回第一个解析的字符,因此忽略(但解析)正确的字符。
**(<++) :: ReadP a -> ReadP a -> ReadP**是关于 choices 的,你提供两个选择作为解析器,你首先尝试运行左边的解析器,如果失败了,第二个解析器。但是在这里,如果第一个解析器匹配,它永远不会为流的其余部分运行第二个解析器。
1条答案
按热度按时间vkc1a9a21#
**
(<*) :: Applicative f => f a -> f b -> f a
**不是特定于ReadP
,它是Applicative
的一部分,本质上可以归结为:字符串
但这是,除非使用
ApplicativeDo
的单子。但它使它相当清楚地发生了什么。在窗帘后面,它被实现为:
型
所以它“合并”了两个
Applicative f => f a
,通过使用const
,它将接受第一个项,而不是第二个。因此,它先使用左操作数,然后使用右操作数,并返回第一个操作数的结果。
因此,在
ReadP
的上下文中,它将运行左边的解析器,然后是右边的解析器,然后忽略右边解析器的结果并返回第一个解析器。举例来说:
型
它将读取 * 两个 * 字符,并返回第一个解析的字符,因此忽略(但解析)正确的字符。
**
(<++) :: ReadP a -> ReadP a -> ReadP
**是关于 choices 的,你提供两个选择作为解析器,你首先尝试运行左边的解析器,如果失败了,第二个解析器。但是在这里,如果第一个解析器匹配,它永远不会为流的其余部分运行第二个解析器。