Haskell 需要柯里化解释

Haskell currying explanation needed

我试图理解柯里化的概念并去了 Haskell documentation。但是,它说

f is the curried form of g

然而 f 有两个参数而 g 只有一个。由于柯里化是将一个接受多个参数的函数转换为一个接受一个参数的函数和 return 另一个函数,所以 'g' 不应该是柯里化函数吗?

来自 haskell 文档

Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed.

f :: a -> b -> c
is the curried form of
g :: (a, b) -> c

所以这对我来说似乎是矛盾的,我也没有看到这两个函数中的任何一个 return 一个函数。

类型a -> b -> c实际上是a -> (b -> c)

所以f不带两个参数,a和一个b和returnc,它只带一个类型的参数a 和 returns b -> c,一个从 bc 的函数。

Yet f takes two arguments and g only one.

不,事实上 两个 函数都有 一个 参数。事实上,在 Haskell 所有 函数中 正好 一个参数。

如果你写这样的签名:

f :: a ->  b -> c

那么这是一个不那么冗长的形式:

f :: a -> (b -> c)

这是如何运作的? f 是一个接受一个参数的函数,然后 returns 另一个 函数 再次接受一个参数。

所以以一个函数为例add :: Int -> Int -> Int

如果我们写add 5 2,那么我们计算5 + 2。看起来是带了两个参数,其实我们写的是(add 5) 2。因此,我们以 5 作为参数调用 add 函数。这returns一个函数(让我们称这个函数为add5 :: Int -> Int)。所以这个 add5 函数将 5 添加到一个数字。因此,如果我们随后调用 add5 2,那么我们将获得 7,因为 add5 returns 5 添加到参数中。

然而,我们可以构建一个函数(如 g),它接受一个二元组参数,因此我们可以使用另一种类型来传递两个值,如 one 参数。事实上你可以看到 g(5, 2) 实际上是 g (5, 2):你 调用 带有 一个 参数的函数,一个二元组(5, 2).

所以柯里化的目的是将这样的 g 函数转换为 一个 参数(一个 2 元组)到一个函数 f 再次接受 一个参数,然后这将构造一个函数,该函数将采用原始二元组的第二个元素。