函数柯里化currying,是函数式编程非常重要的一个标志。它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去。我们依靠这个特性编写很多优雅酷炫的代码。那我们来看一下最简单的实现。

大家一般都是举addSum的例子,我当然也不例外。

add = (num1)->
return (num2)->
return num1 + num2; add3 = add(3);
add5 = add(5); add3(5) # 返回8
add5(5) # 返回10

上述例子其实已经对柯里化的实现,有一个非常好的了解了。其实也就是“分步求值”,我们可以把第一个参数通过闭包保存起来,以供return出去的匿名函数使用。所以我们可以根据add来自定义各种各样的新函数。


我们要使某个函数可以柯里化,难道一定要在函数创建时,就具有柯里化的特性么?假设我们的add函数,起初并不具有柯里化特性的,我们需要怎么做才能让它柯里化呢?

add = (num1, num2)->
return num1 + num2; curry = (fn)->
args = [].slice.call(arguments, 1);
return ()->
[].push.apply(args, arguments);
return fn.apply(this, args); add5 = curry(add, 5)
add5(3) # 返回8

原理还是一样的,我们通过curry函数,让fn需要的第一次的参数通过闭包保存在args的变量里,以供匿名函数使用。最后结合第二次需要的参数,使用apply一次性导入args,完成操作。


上述我们看到的都是分两步求值,这其实并不符合我们更丰富的实际需求。我们需要考虑如何才可以将函数柯里化变成我们需要的想分步便分步,想停止便停止呢?

首先我们需要约定一个规则,这个规则和大部分的Getter/Setter方法一样。当函数没有参数时,执行的是Getter,而有参数的话,则是执行“Setter”。(这个也是Javascript实现简陋的函数重载的一种方法)

curry = (fn)->
args = [];
return ()->
if arguments.length == 0
return fn.apply(this, args);
else
[].push.apply(args, arguments);
return arguments.callee; addSum = ()->
sum = 0;
for num in arguments
sum += num;
return sum; currySum = curry(addSum); currySum(1, 2, 3);
currySum(1);
currySum(1);
currySum(1);
currySum(1);
currySum(); # 返回 10

实现原理其实也很简单,通过闭包,将每次的参数保存在args数组了。当不传参执行Getter时,就直接通过apply函数,将数组参数导入。我们只需要在addSum函数那里处理好导入的参数数组即可。

更多的柯里化带来的妙处,则需要你在实际使用中,细细品味。相信一旦你掌握了这个灵活可靠的方法,可以为你带来不一样的感受。

Javascript函数柯里化(curry)的更多相关文章

  1. JavaScript函数柯里化的一些思考

    1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函 ...

  2. Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象

    1  参数(类型)推断 参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以 ...

  3. JavaScript函数柯里化

    函数式 JavaScript是以函数为一等公民的函数式语言.函数在JavaScript中也是一个对象(继承制Function),函数也可以作为参数传递成函数变量.最近几年函数式也因为其无副作用的特性. ...

  4. 函数柯里化 curry

    一.函数柯里化的特性: (1)参数复用 $.ajax // 示例一 function ajax(type,url,data) { var xhr = new XMLHttpRequest(); xhr ...

  5. javascript函数柯里化初探

    // 柯里化之前 function add(x,y,z){ return x+y+z; } add(1,2,3) // 6 // 柯里化之后 function curryAdd(x){ return ...

  6. 深入理解javascript函数进阶系列第二篇——函数柯里化

    前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...

  7. 前端进击的巨人(五):学会函数柯里化(curry)

    柯里化(Curring, 以逻辑学家Haskell Curry命名) 写在开头 柯里化理解的基础来源于我们前几篇文章构建的知识,如果还未能掌握闭包,建议回阅前文. 代码例子会用到 apply/call ...

  8. 简单粗暴详细讲解javascript实现函数柯里化与反柯里化

    函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...

  9. JavaScript中的事件循环机制跟函数柯里化

    一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...

随机推荐

  1. 什么是PHP Guzzle?

    Guzzle是一个使得利用PHP实现发送HTTP 请求,方便和web service集成的PHP 客户端模拟组件.一句话,它就像一个PHP写的浏览器.当你的服务端程序需要作为客户端来访问其他的serv ...

  2. 移植linux(1)

    硬件环境:TQ2440   软件环境:linux-2.6.30.4 下载源码:ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar ...

  3. 09day1

    词编码 模拟 [问题描述] 一个发送机可以通过一条隧道发送一些以二进制代码组成的单词.在其尽头的接受机可以使用特殊技术恢复到最初的单词.每个单词最初都由0和1组成.所有的单词最初长度都为n(4< ...

  4. 【转】Qt多线程操作界面---在QThread更新QProgressBar

    #include <QApplication> #include <QThread> #include <QMainWindow> #include <QPr ...

  5. SeuRain的归来

    不知不觉二十载寒窗苦读要结束了,还没有到回顾过去的时候.马上进入研三了,现在要努力加油了.还记得曾经的那个在凌晨两点奋战的宇么?归来吧!

  6. Android Studio 小技巧合集

    本文翻译自 Android Studio Tips by Philippe Breault,一共收集了62个 Android Studio 使用小技巧和快捷键. 根据这些小技巧的使用场景,本文将这62 ...

  7. Ubuntu跬步之图片管理digiKam

    Ubuntu下自带了Image Viewer,具备基本的图片浏览功能. 偶尔有些图片需要分组,添加标注,幻灯片浏览等,所以找了款图片管理软件digiKam. 安装 Ubuntu Software Ce ...

  8. IClassSchemaEdit修改要素类信息

    private void ChangeFeatureClassAliasName(IFeatureClass pFeatureClass, string aliasName) { ISchemaLoc ...

  9. 嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)

    Uboot_Kernerl_Add_Watch_Dog: U-Boot 2010.06 (Nov 01 2013 - 15:28:44) DRAM:  128 MiBCheck spi flash c ...

  10. Yii: 设置数据翻页

    一种方法是使用CPagination处理翻页需要的数据如:总数据项数,每页数据项数,当前页,然后在视图中使用CBasePager来绘制. 控制器动作的代码示范: function actionInde ...