了解Haskell优先级规则如何处理多个部分应用程序

了解Haskell优先级规则如何处理多个部分应用程序,haskell,Haskell,请解释Haskell如何确定节、具有多个参数的函数和多个部分应用函数的优先级。有时,当整个表达式接受多个参数时,我发现很难确定哪个部分函数将应用哪个参数 下面是一些示例函数,但是我相信不同的示例可能更具说明性。第一篇摘自《带效果的应用程序编程》一文 sequence :: [IO a] → IO [a] sequence [] = return [] sequence (c : cs) = return (:) `ap` c `ap` sequence cs (.) (.) (.) (.) (

请解释Haskell如何确定节、具有多个参数的函数和多个部分应用函数的优先级。有时,当整个表达式接受多个参数时,我发现很难确定哪个部分函数将应用哪个参数

下面是一些示例函数,但是我相信不同的示例可能更具说明性。第一篇摘自《带效果的应用程序编程》一文

sequence :: [IO a] → IO [a]
sequence [] = return []
sequence (c : cs) = return (:) `ap` c `ap` sequence cs

(.) (.)
(.) (.) (.)

是否有工具将此类表达式转换为lambda表达式形式?

括号中没有参数的运算符与普通标识符一样处理。因此,
(+)
添加
的行为方式完全相同。这意味着它是以前缀形式使用的,并且不会出现优先级问题

考虑到这一点,我们可以想象写以下内容:

compose = (.)
compose compose compose
后一个版本与使用
()
的混乱版本相同。这有助于记住函数应用程序是右关联的,因此表达式与:

(compose compose) compose
带有参数的运算符部分,如
(+1)
(1+)
就优先级而言,其行为与普通标识符类似。因此,如果定义
next=(+1)
,两者的行为将相同

就无点代码而言,该包有一个命令行工具,它接受一个无点函数,并尝试将其转换为一组lambda。您还可以通过@unpl从#haskell IRC频道上的lambdabot获得此功能

您只需安装pointful with cabal并将其命名为:

cabal install pointful
pointful

函数应用程序(如
abcd
中的标识符列表被解析为
((ab)c)d)
。括号中的中缀运算符
(.)
被视为标识符

所以
()(
解析为
(()()(

通常,像这样的变量运算符

`functionname`
默认情况下,具有左关联性,且优先级低于函数应用程序,但这可以通过
infixl
infixr
声明进行修改。
ap
功能未从默认值修改,因此
sequence
pase的rhs为:

((return (:)) `ap` c) `ap` (sequence cs)
或同等地

ap (ap (return (:)) c) (sequence cs)

如果您在#haskell irc频道,您可以使用@unpl,它将无点版本转换为点完整(lambda)版本。(.)的示例:(\c e f i->c(e f i))为什么不将其解析为
(compose)
,因为compose需要两个参数?@Rumca在Haskell中,每个函数只需要一个参数。有些,如
编写
,然后返回一个带有另一个参数的函数。“优先级低于函数应用程序,但这是可以修改的”这句话有点别扭,人们可以读它,就好像
中缀
声明可以使优先级高于函数应用程序一样。为什么
(返回(:)`ap`
不是
ap
返回(:)
的应用,而是作为一个节来读?部分是否总是像这里这样“翻译”到
ap(return(:)
?@Rumca我不知道你这里所说的“部分”是什么意思。(x`f`y)解析为
fxy
,而x`f`y`f`z解析为(x`f`y)`f`z,或
f(fxy)z
。至于原因,我只能让你参考第3.2节。