Haskell readP 中的 <* 有什么作用?

What does <* in Haskell readP do?

提问人:Piskator 提问时间:10/26/2023 更新时间:10/26/2023 访问量:87

问:

我在 Haskell 库中遇到过几次,但我还不确定它的作用,并且在库文档中找不到它。和一样吗?<*readP<++

解析 Haskell 函数式编程 单子

评论

0赞 cafce25 10/26/2023
你没找到它是什么意思?Hoogle有它
0赞 Piskator 10/26/2023
啊,谢谢。那是因为我试图用谷歌找到它,我以为它是一个库函数,它似乎只是一个单元运算符。readP
0赞 Piskator 10/26/2023
@cafce25根据 Hoogle 的描述,我仍然不确定它的确切功能。以及它与 的不同之处,我在 Hoogle 上看到了类型定义和一些稀疏的描述,例如 Sequence 操作,丢弃了第二个参数的值。但是,这是什么意思,第二个单子在中被忽略了?那么副作用会被预先预防吗?<*>f a -> f b -> f a

答:

6赞 willeM_ Van Onsem 10/26/2023 #1

(<*) :: 应用 f => f a -> f b -> f a 不是特定于 , 它是 部分 或 , 基本上可以归结为:ReadPApplicative

f <* g = do
  y <- f
  g
  pure y

但这是,除非使用 FOR Monads。但它清楚地表明了正在发生的事情。ApplicativeDo

在幕后,它被实现为:

f <* g = liftA2 const f g

所以它“合并”了两个 S,并且通过使用 ,它将采用第一项,而不是第二项。Applicative f => f aconst

因此,它使用左操作数,然后使用右操作数,并返回第一个操作数的结果。

因此,在 的上下文中,它将运行左边的解析器,然后运行右边的解析器,然后省略右边解析器的结果并返回第一个解析器。ReadP

例如:

get <* get

它将读取两个字符,并返回第一个解析的字符,因此忽略(但解析)正确的字符。

(<++) :: ReadP a -> ReadP a -> ReadP 是关于选择的,其中您提供两个选项作为解析器,然后您首先尝试运行左侧解析器,如果失败则运行第二个解析器。但是在这里,例如,如果第一个解析器匹配,它永远不会为流的其余部分运行第二个解析器。