类似
addList :: [int] -> int
addList = foldl1 (+)
为什么这样做? Currying部分。为什么没有变量?
答案 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 (+)
。
这条规则是基于两个函数相等的想法,如果它们在应用于相同的参数时给出相同的结果。这里的两个函数是f
和g = \x -> f x
f : a -> b
,我们想要显示所有c : a
,f c = g c
。要证明它需要任意c : a
并将其应用于g
:g c = (\x -> f x) c = f c
,最后一个等式是另一个名为beta reduction的规则,它表示函数应用程序是通过替换来计算的。
答案 2 :(得分:2)
来自sepp2k的解释是正确的,我只是想指出(双关语)这个currying的应用程序有一个名字:它被称为“无点样式”。这是一个很好的解释,包括优点和缺点:http://www.haskell.org/haskellwiki/Pointfree