一般来说,柯里化是指将一个双参数函数转换为一个接受一个参数并返回另一个单参数函数的函数,这样第一个参数调用柯里化函数的结果与第二个参数调用 this 的结果是等价的使用两个参数调用原始(未咖喱)函数。在具有闭包和动态类型(或类型推断)的伪 C 语言中,这看起来像这样:
// The original, uncurried function:
function f(a, b) { return 2 * a - b; }
// The curried function:
function g(a) {
return function(b) {
return f(a, b);
}
}
// Now we can either call f directly:
printf("%i\n", f(23, 42));
// Or we can call the curried function g with one parameter, and then call the result
// with another:
printf("%i\n", (g(23))(42));
通过多次柯里化,我们可以将任何多参数函数简化为一组嵌套的单参数函数。
在 Haskell 中,所有函数都是单参数的;like 的构造f a b c
实际上等价((f(a))(b))(c)
于我们虚构的 C-with-closures。将多个参数真正传递给函数的唯一方法是通过元组,例如f (a, b, c)
- 但由于柯里化函数的语法更简单,语义更灵活,因此很少使用此选项。
Haskell Prelude 定义了两个函数,curry
并uncurry
在这两个表示之间进行转换:curry
is of type ((a,b) -> c) -> a -> b -> c
,即它接受一个接受元组(a, b)
并返回 a的单参数函数,c
并将其转换为 type 的函数a -> b -> c
,即函数接受a 并返回一个接受 a并返回a
a 的函数。做相反的事情。b
c
uncurry
部分应用并不是真正的事情。它只是给你有一个柯里化函数(例如f a b
)的情况命名,而不是完全展开整个链(例如,f 23 42
),你在途中的某个地方停下来,并进一步传递结果函数,例如let g = f 23
。为了部分应用一个函数,它必须是柯里化的(你不能部分地应用f (a, b)
as let g = f (a)
),但是由于在 Haskell 中以柯里化的方式编写函数是默认的,部分应用是简单且常见的做法。