3

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

以下是一些示例函数,但我相信不同的示例可能更具说明性。第一个取自“带有效果的应用程序编程”一文。

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

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

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

4

2 回答 2

8

括号中没有参数的运算符被视为普通标识符。因此(+)add行为方式完全相同。这意味着它以前缀形式使用,根本不会出现优先级问题。

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

compose = (.)
compose compose compose

后一个版本与使用(.). 记住函数应用是右结合的,所以表达式是一样的:

(compose compose) compose

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

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

您可以使用 cabal 安装 pointful 并调用它:

cabal install pointful
pointful
于 2013-06-21T19:44:24.117 回答
3

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

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

一般来说,像这样的变量运算符

`functionname`

默认情况下具有左关联性,并且优先级低于函数应用程序,但这可以使用infixlorinfixr声明进行修改。该ap函数未从默认值修改,因此 rhs 的sequence内容为:

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

或等效地

ap (ap (return (:)) c) (sequence cs)
于 2013-06-21T20:02:34.260 回答