Haskell - 柯里化?需要进一步解释
那么为什么
addList :: [int] -> int
addList = foldl1 (+)
这有效?柯里化部分。为什么没有变量?
So something like
addList :: [int] -> int
addList = foldl1 (+)
Why does this work? The Currying part. Why no variable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您定义像
fxy = bla
这样的函数,则与fx = \y -> bla
,与f = \x -> 相同(\y -> bla)
。换句话说,f
是一个函数,它接受一个参数x
,并返回另一个函数,该函数接受一个参数y
,然后返回实际结果。这称为柯里化。类似地,当您执行
fx y
时,它与(fx) y
相同。即,您使用参数x
调用函数f
。这将返回另一个函数,您将其应用于参数y
。换句话说,当您执行
addList xs = Foldl1 (+) xs
时,您首先调用foldl1 (+)
,然后返回另一个函数,您将其应用于 <代码>xs。因此,由于foldl1 (+)
返回的函数实际上与addList
相同,因此您可以将其缩短为addList = Foldl1 (+)
。If you define a function like
f x y = bla
, this is the same asf x = \y -> bla
, which is the same asf = \x -> (\y -> bla)
. In other wordsf
is a function which takes one argument,x
, and returns another function which takes one argument,y
, and then returns the actual result. This is known as currying.Analogously when you do
f x y
, it's the same as(f x) y
. I.e. you're calling the functionf
with the argumentx
. This returns another function, which you apply to the argumenty
.So in other words when you do
addList xs = foldl1 (+) xs
, you're first callingfoldl1 (+)
which then returns another function, which you apply toxs
. So since the function returned byfoldl1 (+)
is actually the same one asaddList
, you can just shorten it toaddList = foldl1 (+)
.除了柯里化之外,正如 sepp2k 指出的那样,这里我们使用所谓的 eta 缩减。它是 lambda 演算的约简规则之一,是 Haskell 的基础。它说
\x ->当
相当于x
不出现在f
中时,f xf
。让我们将其应用到您的案例中。我想您对像
addList xs = Foldl1 (+) xs
这样的定义感到满意。我们可以将其重写为addList = \xs -> Foldl1 (+) xs
现在应用 eta 缩减规则,我们得到addList = Foldl1 (+)
。该规则基于以下思想:如果两个函数在应用于相同参数时给出相同的结果,则它们相等。这里的两个函数是
f
和g = \x ->; f x
其中f : a -> b
,我们想要证明对于所有c : a
,fc = g c
。为了证明它需要任意的c : a
并将其应用于g
:gc = (\x -> fx) c = f c
,最后一个等式是由另一个称为 beta 归约的规则决定的,该规则表示函数应用是通过替换来评估的。Besides currying, as sepp2k pointed out, here we use the so called eta reduction. It's one of the reduction rules of lambda calculus which is the basis of Haskell. It says that
\x -> f x
is equivalent tof
whenx
does not appear inf
.Lets apply it to your case. I guess you are comfortable with a definition like
addList xs = foldl1 (+) xs
. We can rewrite this asaddList = \xs -> foldl1 (+) xs
and now applying the eta reduction rule we getaddList = foldl1 (+)
.This rule is based on the idea that two functions are equal if they give equal results when applied to the same arguments. The two functions here are
f
andg = \x -> f x
wheref : a -> b
and we want to show that for allc : a
,f c = g c
. To prove it take an arbitraryc : a
and apply it tog
:g c = (\x -> f x) c = f c
, the last equality is by another rule called beta reduction which says that function application is evaluated by substitution.sepp2k 的解释是正确的,我只是想指出(双关语)这种柯里化应用有一个名字:它被称为“无点风格”。这是一个很好的解释,包括优点和缺点: http://www.haskell.org/haskellwiki/Pointfree
The explanation from sepp2k is correct, I just want to point out (pun intended) that this application of currying has a name: It's called "point-free style". Here is a good explanation, including the pros and cons: http://www.haskell.org/haskellwiki/Pointfree