Function Programming - 柯里化(curry)
看到一篇非常不错的文章,这里分享给大家:http://www.jianshu.com/p/fa3568087881。
首先,柯里化的定义:你可以只透过部分的参数呼叫一个function,它会回传一个function 去处理剩下的参数。
我们从最简单的栗子开始:
var add = function(a) {
return function(b) {
return a + b;
}
}
var addTen = add(10);
addTen(5); // 15
同时,我们还可以这样调用:
add(10)(5); //15
上述add函数是柯里化之后的函数,一般我们会如下定义add函数:
var add = function(a, b) {
return a + b;
}
一般的定义有什么问题呢,参数可能不小心多了,那多余的参数就会被忽略,也有可能传参传少了,那么函数执行会发生错误;而柯里化如果传部分参数只会返回要处理剩下参数的函数,make sense?
当然我们有工具使我们的函数柯里化,这里我们举例用lodash的https://lodash.com/docs/4.17.4#curry:
var add = _.curry(function(a, b) {
return a + b;
})
var addTen = add(10); addTen(5); // 15 同时,柯里化也接受传多个参数: add(10)(5); //15
我们再稍微深入理解一下:
var object = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getIds = object.map(o => (o.id));
上述代码明显是取objec里面各个id;这有个什么问题呢?我们没有办法重用getIds这个函数,因为每次想拿到id,都得进行一次map和取id的操作,我们再改进下这个函数:
var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getId = (object) => (object.id);
var getIds = objects.map(getId); //解释下为啥这里可以不用参数直接可以调用getId,因为fp(Function Programming)中函数是一等公民,function(a) {return getId(a);} 与 getId是等价的;
这样的,我们抽出去里getId这个函数,但是依然不能完全重用,因为每次还要进行一次map操作,再一次改进:
var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getId = (object) => (object.id);
var getIds = _.curry((objects) => objects.map(getId));
getIds(objects); //[1,2,3]
这个时候我们就用到里柯里化,但是依然不够好,因为如果我想拿到每个object的name呢,这个方法就做不到,我们就再一次改进看看:
var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getValues = _.curry((objects, key) => objects.map((object) => (object[key])));
getValues(objects, 'name')
这样的话,我们就能取任何key的值了,只需要传入objects和key即可。
var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getId = _.curry((property, object) => (object[property]));
var map = _.curry((fn, objects) => objects.map(fn));
var getValues = map(getId('id'));
getValues(objects);
由于我们对key值进行的操作可能不一样,所以我们可以传一个函数;
这就是我们所介绍的curry啦,欢迎各位留言,提反馈!
Function Programming - 柯里化(curry)的更多相关文章
- Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象
1 参数(类型)推断 参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以 ...
- 函数柯里化 curry
一.函数柯里化的特性: (1)参数复用 $.ajax // 示例一 function ajax(type,url,data) { var xhr = new XMLHttpRequest(); xhr ...
- Javascript函数柯里化(curry)
函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...
- JS 柯里化 (curry)
用 JS 理解柯里化 函数式编程风格,试图以函数作为参数传递(回调)和无副作用的返回函数(修改程序的状态). 很多语言采用了这种编程风格.JavaScript,Haskell,Clojure,Erla ...
- JavaScript函数柯里化的一些思考
1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函 ...
- js函数式编程(二)-柯里化
这节开始讲的例子都使用简单的TS来写,尽量做到和es6差别不大,正文如下 我们在编程中必然需要用到一些变量存储数据,供今后其他地方调用.而函数式编程有一个要领就是最好不要依赖外部变量(当然允许通过参数 ...
- 前端进击的巨人(五):学会函数柯里化(curry)
柯里化(Curring, 以逻辑学家Haskell Curry命名) 写在开头 柯里化理解的基础来源于我们前几篇文章构建的知识,如果还未能掌握闭包,建议回阅前文. 代码例子会用到 apply/call ...
- curry柯里化函数实现
curry柯里化函数实现 参考文章: 一行写出javascript函数式编程中的curry 感谢作者分享 第一步: 缓存原始函数的参数个数 function curry(fn) { var limit ...
- Scala函数柯里化(Currying or Curry)
柯里化(Currying) 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 简单的实现如下: scala> def ...
随机推荐
- JS前端三维地球渲染——中国各城市航空路线展示
前言 我还从来没有写过有关纯JS的文章(上次的矢量瓦片展示除外,相对较简单.),自己也学习过JS.CSS等前端知识,了解JQuery.React等框架,但是自己艺术天分实在不过关,不太喜欢前端设计,比 ...
- C++基础知识1
1 初始C++ 1.1 编写一个简单的C++程序 1.1.1 程序结构 每个C++程序都包括一个或多个函数(function),但只有一个主函数main.操作系统通过调用 main来运行C++程序. ...
- 12.21-Android WebService(基于KSOAP2)
KSOAP2_连接WebService *****我是小知识点******** Ksoap2提供了对soap序列化更好的支持.Ksoap2是一个轻量级的J2ME平台的实现框架,提供了soap协议消息的 ...
- Memcached查找命令
Memcached各个查找命令的语法格式都类似,且有相同的参数和参数含义,先将可能出现的各个参数的意义说明如下 key:键值 key-value 结构中的 key,用于查找缓存值. noreply(可 ...
- 【20171025中】alert(1) to win 脚本渲染自建
游戏误人生,一下午玩了将近四个小时的三国杀,后悔不已,然后重新拾起xss challenge,突发奇想,自己构建渲染后的html. 从最简单的开始. 自动检测html: <!DOCTYPE ht ...
- Vue源码后记-其余内置指令(2)
-- 指令这个讲起来还有点复杂,先把html弄上来: <body> <div id='app'> <div v-if="vIfIter" v-bind ...
- 使用jQuery中trigger()方法自动触发事件
一.常用事件 在页面加载完成时 自动触发input的点击事件,在移动端可以实现自动弹出输入法,获得焦点 $("input").trigger("click") ...
- RabbitMQ 默认端口号
4369 (epmd), 25672 (Erlang distribution) 5672, 5671 (AMQP 0-9-1 without and with TLS) 15672 (if mana ...
- keepalived中的脑裂
在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体.动作协调的HA系统,就分裂成为2个独立的个体.由于相互失去了联系,都以为是对方出了故障.两个节点上的HA软件像“裂脑人”一样,争 ...
- JsDoc脚本注释文档生成
使用jsDoc可使用特定注释,将注释的内容生成文档,可用于生成脚本库的API文档 jsdoc 文档: http://usejsdoc.org/