柯里化

柯里化

> LeekScript 教程

本页内容已部分过时。在 LeekScript 中,柯里化如今只能让代码更易读,已经不能再节省操作数了,因为调用函数的开销已改为固定 1 个操作数,与参数个数无关。

在函数式编程中,柯里化指的是这样一种变换:把一个接受多个参数的函数,变成一个只接受一个参数、并返回另一个函数(由它接收剩下的参数)的函数。反向操作当然也是可以的,称为反柯里化。

这个术语得名于美国数学家 Haskell Curry。

LeekScript 示例

我们来看一个接受 2 个参数、返回二者之和的函数:

function add(x, y) { return x + y; }

它可以改写成柯里化的形式:

function add_curried(x) { return function(y) { return x + y; }; }

用法示例:

//常规写法 var somme = add(1, 3);

//柯里化写法 var add1 = add_curried(1); var somme = add1(3);

这个例子只是为了简单演示它的原理,在这种情况下用柯里化并没有什么好处。我们来看一个更有意思的例子。 假设我们有一个包含 n 个数字元素的数组,想给所有元素都加 1。

//常规写法 for(var key:var element in array) { array[key] = add(1, element); }

//柯里化写法 var add1 = add_curried(1); for(var key:var element in array) { array[key] = add1(element); }

这里的好处体现在优化上:在循环中,我们不再调用一个有 2 个参数的函数,而是只调用一个有 1 个参数的函数。数组中的元素越多,节省的就越多。

什么时候适合柯里化?

如前所述,柯里化主要用于在循环中调用的函数,并且该函数有一个或多个参数与循环无关。 记忆化 就是一个绝佳的应用场景。

以我们带记忆化的 lineOfSight 函数为例(定义见这里):

如果在循环中调用这个函数,这两个操作数的开销就会拖累我们! 柯里化可以帮上忙:

我们的函数返回了另一个函数,而返回的函数可以使用第一个函数的参数。第一次接触时可能有点难懂,但用得好的话,这个方法非常高效! 留个小练习:这个函数还能进一步优化,看你能不能找到办法!