Haskell - Currying?需要进一步解释

时间:2010-09-25 15:23:50

标签: haskell currying partial-application

类似

addList :: [int] -> int
addList = foldl1 (+)

为什么这样做? Currying部分。为什么没有变量?

3 个答案:

答案 0 :(得分:11)

如果您定义类似f x y = bla的功能,则与f x = \y -> bla相同,这与f = \x -> (\y -> bla)相同。换句话说,f是一个函数,它接受一个参数x,并返回另一个带有一个参数y的函数,然后返回实际结果。这被称为currying。

类似于f x y时,它与(f x) y相同。即您正在使用参数f调用函数x。这将返回另一个函数,您将其应用于参数y

换句话说,当您执行addList xs = foldl1 (+) xs时,您首先调用foldl1 (+),然后返回另一个函数,您将其应用于xs。因此,foldl1 (+)返回的函数实际上与addList相同,您可以将它缩短为addList = foldl1 (+)

答案 1 :(得分:5)

除了currying,正如sepp2k所指出的,这里我们使用所谓的eta reduction。这是lambda演算的缩减规则之一,它是Haskell的基础。它表示当\x -> f x未显示在f时,x相当于f

让我们将它应用到您的案例中。我想你对addList xs = foldl1 (+) xs之类的定义感到满意。我们可以将其重写为addList = \xs -> foldl1 (+) xs,现在应用eta缩减规则,我们得到addList = foldl1 (+)

这条规则是基于两个函数相等的想法,如果它们在应用于相同的参数时给出相同的结果。这里的两个函数是fg = \x -> f x f : a -> b,我们想要显示所有c : af c = g c。要证明它需要任意c : a并将其应用于gg c = (\x -> f x) c = f c,最后一个等式是另一个名为beta reduction的规则,它表示函数应用程序是通过替换来计算的。

答案 2 :(得分:2)

来自sepp2k的解释是正确的,我只是想指出(双关语)这个currying的应用程序有一个名字:它被称为“无点样式”。这是一个很好的解释,包括优点和缺点:http://www.haskell.org/haskellwiki/Pointfree