谈谈函数式编程curry
Curry概念
The concept is simple: You can call a function with fewer arguments than it expects. It returns a function that takes the remaining arguments.
当你调用一个函数的时候,传入的参数小于函数预期的个数时候它将返回一个新的函数,再来调用剩下的那些参数。
函数预期的参数个数其实就是函数的length属性所返回的个数。其中不包括(ES6的剩余参数)。
简单的实现
const add = x => y => x + y;
const increment = add(1);
const addTen = add(10);
increment(2); // 3
addTen(2); // 12
其中关键点就在于利用闭包来将参数收集起来。
curry有什么用
说实话当我第一次学习的时候,那已经是好几个月之前的事情了,当时看了下和上面代码类似的例子,也能看懂概念和原理。不过还是由于处于初学的状态加上没有感受过中大型项目的洗礼(现在也没233)开发经验不足,认为这个curry好像没啥特别的用处嘛。加10我就直接加10好了,加1就直接加1好了,不是本来就十分方便吗,反而这样更麻烦,因此没有加以重视。但是上面只是一个简单的例子从中来解释curry的概念,如果它的用途真的只是用来加法运算那却是是没什么用了。
以下几个例子来源于mostly-adequate-guide chapter04:Curring
const curry = require('lodash').curry;
const match = curry((what, s) => s.match(what));
const replace = curry((what, replacement, s) => s.replace(what, replacement));
const filter = curry((f, xs) => xs.filter(f));
const map = curry((f, xs) => xs.map(f));
策略性地把要操作的数据(String, Array)放到最后一个参数里。到使用它们的时候你就明白这样做的原因是什么了。
match(/r/g, 'hello world'); // [ 'r' ]
const hasLetterR = match(/r/g); // x => x.match(/r/g)
hasLetterR('hello world'); // [ 'r' ]
hasLetterR('just j and s and t etc'); // null
filter(hasLetterR, ['rock and roll', 'smooth jazz']); // ['rock and roll']
const removeStringsWithoutRs = filter(hasLetterR); // xs => xs.filter(x => x.match(/r/
g))
removeStringsWithoutRs(['rock and roll', 'smooth jazz', 'drum circle']); // ['rock and
roll', 'drum circle']
const noVowels = replace(/[aeiou]/ig); // (r,x) => x.replace(/[aeiou]/ig, r)
const censored = noVowels('*'); // x => x.replace(/[aeiou]/ig, '*')
censored('Chocolate Rain'); // 'Ch*c*l*t* R**n'
通过收集参数,传递小于函数预期个数的参数给调用函数,就能得到一个记住了这些参数的新函数。
这样通过不断地部分参数的传递得到新的能够通用的函数,就能将代码更好地复用。
成长有限,目前还是没能实际使用编写过函数式编程的代码,但也能确确实实地感受到它的价值了,也算是一种进步了。
讲讲curry的实现
lodash.js curry
var abc = function(a, b, c) {
return [a, b, c];
};
var curried = _.curry(abc);
curried(1)(2)(3);
// => [1, 2, 3]
curried(1, 2)(3);
// => [1, 2, 3]
curried(1, 2, 3);
// => [1, 2, 3]
curry使用
- 当我们传递的参数个数等于目标函数的预期个数的时候直接返回结果
- 当传递的参数小于预期函数的时候,返回一个新的函数,这个函数此时已经收集了之前传递进去的所有参数了,现在你只要将剩余的参数传入即可
实现的关键点
- 预期函数的个数,实际就是
function.length - 返回新的包含之前参数的函数。实际就是利用
Function.prototype.bind
主体功能实现:
function curry(targetfn) {
// 预期参数个数
var numOfArgs = targetfn.length;
return function curried() {
// 参数个数小于的话把之前传入的参数收集起来,再次返回curry化的函数
if (arguments.length < numOfArgs) {
return curried.bind(null, ...arguments);
// without ES6
// return Function.prototype.bind.apply(curried, [null].concat(Array.prototype.slice.call(arguments)));
} else {
return targetfn.apply(null, arguments);
}
}
}
这种方法利用的是闭包,将targetfn和numOfArgs私有化,变成内部变量
当传递的参数等于numOfArgs时候,调用targetfn
参考
谈谈函数式编程curry的更多相关文章
- restapi(7)- 谈谈函数式编程的思维模式和习惯
国庆前,参与了一个c# .net 项目,真正重新体验了一把搬砖感觉:在一个多月时间好像不加任何思考,不断敲键盘加代码.我想,这也许是行业内大部分中小型公司程序猿的真实写照:都是坐在电脑前的搬砖工人.不 ...
- js函数式编程curry与compose实现
//自行实现以下curry函数和compose //curry function curry(fn) { return function aa (...arg) { if (arg.length &g ...
- 函数式编程之柯里化(curry)
函数式编程curry的概念: 只传递给函数一部分参数来调用函数,然后返回一个函数去处理剩下的参数. var add = function(x) { return function(y) { retur ...
- laravel中closure和curry 科里化函数式编程
推荐值得的一看博客文档:谢谢作者 : https://my.oschina.net/zhmsong 函数式编程curry的概念: 只传递给函数一部分参数来调用函数,然后返回一个函数去处理剩下的参数. ...
- 翻译连载 | 附录 A:Transducing(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- C#函数式编程
提起函数式编程,大家一定想到的是语法高度灵活和动态的LISP,Haskell这样古老的函数式语言,往近了说ruby,javascript,F#也是函数式编程的流行语言.然而自从.net支持了lambd ...
- Atitit 函数式编程与命令式编程的区别attilax总结 qbf
Atitit 函数式编程与命令式编程的区别attilax总结 qbf 1.1. 函数式程序就是一个表达式.命令式程序就是一个冯诺依曼机的指令序列. 命令式编程是面向计算机硬件的抽象,有变量(对应着存 ...
- JavaScript 与函数式编程
原文:https://bethallchurch.github.io/JavaScript-and-Functional-Programming/ 译文:http://www.zcfy.cc/arti ...
- C#函数式编程之由函数构建函数
在面向对象的编程中,如果我们需要复用其他的类,我们可以通过继承来实现.而在函数式编程中我们也可以采取不同的方式来复用这些函数.今天的教程将会讲述两种方式,其中一个就是组合,将多个函数组合成为一个函数, ...
随机推荐
- 5G时代,行业市场用户的公网与专网如何选择
导读 今年,5G开启了真刀真枪的商用元年,尤其中国5G正式启动商用服务,5G规模商用进程再次大提速.除了面向消费者领域,5G更大的商业价值还是寄望于进入各个垂直行业,赋能千行百业数字化转型. 5G进入 ...
- 搭建DHCP服务
DHCP服务流程 1.DHCP客户端初次接入网络时,会发送DHCP发现报文(DHCP Discover),用于查找和定位DHCP服务器. 2.DHCP服务器在接收到DHCP发现报文后,发送DHCP提供 ...
- scrapy shell中遇到的坑
如果直接scrapy shell +网址 然后发现返回200 但是request和response的网址不同,那么可以使用百度短网址 https://dwz.cn/ 进行缩短.这样一般就能解决问题
- Day11 - J - Brave Game HDU - 1846
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫<勇敢者的游戏>(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻.今天,大家选择上 ...
- Flask 教程 第二十三章:应用程序编程接口(API)
本文翻译自The Flask Mega-Tutorial Part XXIII: Application Programming Interfaces (APIs) 我为此应用程序构建的所有功能都只适 ...
- GreenPlum 提取数据表信息
参考: https://www.alberton.info/postgresql_meta_info.html https://my.oschina.net/Kenyon/blog/226600 列信 ...
- 在fragment中实现返回键单击提醒 双击退出
最近在练习一个小项目,也就是郭霖大神的开源天气程序,尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成. 项目地址 接近完成的时候,想在天气信息页面实现一个很常见的功能,也 ...
- IDEA配置数据库连接失败的问题
今天采用IDEA连接数据库失败了,有几个问题需要注意 首先笔者采用的数据库版本为8.0.17而IDEA自带版本是5.2.26大概,于是首先出现的问题是驱动不匹配,那么就需要换成我自己的版本,配置如下 ...
- drugs
1. 摘录:未来简史 2. 毒品禁药扫盲 3. 毒品争议 4. 部分毒品列表 5. 影视作品里常出现的几种毒品 1. 摘录:未来简史 第一章 人类的新议题 幸福快乐的权利 (P36) 人们喝酒是为了遗 ...
- 洛谷 P1886 滑动窗口 /【模板】单调队列
纯板子题,入队时保证单调性,即单调栈,出队保证题目条件,本题即窗口长度k,在入队出队时都可以维护信息 ; int buf[maxm], maxq[maxm], minq[maxm], ans1[max ...