Haskell - 柯里化?需要进一步解释

发布于 2024-09-25 01:53:32 字数 113 浏览 5 评论 0原文

那么为什么

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

这有效?柯里化部分。为什么没有变量?

So something like

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

Why does this work? The Currying part. Why no variable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱格式化 2024-10-02 01:53:32

如果您定义像 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 as f x = \y -> bla, which is the same as f = \x -> (\y -> bla). In other words f 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 function f with the argument x. This returns another function, which you apply to the argument y.

So in other words when you do addList xs = foldl1 (+) xs, you're first calling foldl1 (+) which then returns another function, which you apply to xs. So since the function returned by foldl1 (+) is actually the same one as addList, you can just shorten it to addList = foldl1 (+).

眼眸印温柔 2024-10-02 01:53:32

除了柯里化之外,正如 sepp2k 指出的那样,这里我们使用所谓的 eta 缩减。它是 lambda 演算的约简规则之一,是 Haskell 的基础。它说 \x ->当x不出现在f中时,f x相当于f

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

该规则基于以下思想:如果两个函数在应用于相同参数时给出相同的结果,则它们相等。这里的两个函数是 fg = \x ->; f x 其中 f : a -> b,我们想要证明对于所有 c : afc = g c。为了证明它需要任意的c : a并将其应用于ggc = (\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 to f when x does not appear in f.

Lets apply it to your case. I guess you are comfortable with a definition like addList xs = foldl1 (+) xs. We can rewrite this as addList = \xs -> foldl1 (+) xs and now applying the eta reduction rule we get addList = 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 and g = \x -> f x where f : a -> b and we want to show that for all c : a, f c = g c. To prove it take an arbitrary c : a and apply it to g: 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.

虫児飞 2024-10-02 01:53:32

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文