函数式编程-柯里化(currying)

news/2023/12/1 9:12:20

何为柯里化

概念:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的

参数且返回结果是新函数的技术。

上栗子

var add = function(x) {
    return function(y) {
        return x + y;
    }
}

var increment = add(1);
var addTen = add(10);

increment(2);
// 3

addTen(2);
// 12

解释:我们定义了一个add函数,这个函数接受一个参数并返回一个新的函数。调用add之后,返回的函数通过闭包可以访问到add的第一个参数。这样可以使这类函数的定义和调用更加容易。

进阶(for our enjoyment)

var curry = require('lodash').curry;
var match = curry(function(what, str) {
    return str.match(what);
})

var replace = curry(function(what, replacement, str) {
    return str.replace(what, replacement);
})

var filter = curry(function(f, array){
    return array.filter(f);
})

match(/s+/g, 'hello world');
// [' ']

match(/s+/g)('hello world');
//[' ']

var hasSpaces = match(/s+/g);
// function(x) { return x.match(/\s+/g) }

hasSpaces('hello world');
//[' ']

hasSpaces('sssss');
// null

var noVowels = replace(/[aeiou]/ig);
// function(replacement, x) { return x.replace(/[aeiou]/ig, replacement) }

var censored = noVowels("*");
// function(x) { return x.replace(/[aeiou]/ig, "*") }

censored("Chocolate Rain");
// 'Ch*c*l*t* R**n'

filter(hasSpaces, ["tori_spelling", "tori amos"]);
// ["tori amos"]

var findSpaces = filter(hasSpaces);
// function(xs) { return xs.filter(function(x) { return x.match(/\s+/g) }) }

findSpaces(["tori_spelling", "tori amos"]);
// ["tori amos"]

这里表明的是一种“预加载”函数的能力,通过传递一到两个参数调用函数,就能得到一个记住了这些参数的新函数。

当我们谈论纯函数的时候,我们常说函数接受一个输入返回一个输出。currying函数所做的正是这样:每传递一个参数调用函数,就返回一个新函数处理剩余的参数。

柯里化的好处

通过简单地传递几个参数,就能动态创建实用的新函数;而且还能带来一个额外好处,那就是保留了函数定义,尽管参数不止一个

如何实现柯里化

var add = function(){
    var sum = 0;
    for(var i = 0, l = arguments.length; i < l; i++){
        sum += arguments[i];
    }
    return sum;
}

var curry = (function(fn){
    var args = [];
    return function(){
        if(arguments.length == 0) {
            return fn.apply(this, args)
        } else {
            [].push.apply(args, arguments);
            return arguments.callee;
        }
    }
})

currySum = curry(add);

currySum(1, 2, 3);
currySum(1);
currySum(1);
currySum(1);
currySum(1);
currySum();
// 10

http://www.niftyadmin.cn/n/2747061.html

相关文章

React源码分析与实现(二):状态、属性更新 - setState

原文链接地址&#xff1a;github.com/Nealyang 转载请注明出处 状态更新 此次分析setState基于0.3版本&#xff0c;实现比较简单&#xff0c;后续会再分析目前使用的版本以及事务机制。 流程图大概如下 setState的源码比较简单&#xff0c;而在执行更新的过程比较复杂。我们直接…

源码专题之spring设计模式:委派模式、工厂模式

委派模式 在常见的23种设计模式中其实并没有委派模式的影子&#xff0c;但是委派模式确实是spring中应用比较多的一种&#xff0c;SpringMVC框架中的DispatcherServlet就是用到了这种模式。下面以项目经理和普通员工的模型来实现一个简单的委派模式。 1.公司员工&#xff0c;包…

ubuntu 16 .04常见指令整理

删除类指令 sudo rm -rf 文件名 //该指令为直接删除指令 -------------------------------------------------------------------------------------------------------------------------------- 移动类指令 mv /home/hu/桌面/gamit10.7/* /opt //将gamit10.7剪切复制到…

python -- 面向对象三大特性

1&#xff0c;继承 1&#xff0c;初识继承 什么是继承&#xff1f; ——继承是一种创建新类的方式&#xff0c;在python中&#xff0c;新建的类可以继承一个或多个父类&#xff0c;父类又可称为基类或超类&#xff0c;新建的类称为派生类或子类。 子类会“遗传”父类的属性&…

实验楼mysql实验-搭建一个简易的成绩管理系统的数据库

网址如下https://www.shiyanlou.com/courses/running &#xff0c;pass之后的体验还蛮好的&#xff0c;。 首先打开终端&#xff0c;双击xfce终端或右键打开终端 开启数据库服务 &#xff0c;连接数据库 首先创建新的数据库create database gradesystem; 接着选择新创建的数据库…

TW实习日记:第31-32天

不知不觉的&#xff0c;实习的净工作天数&#xff0c;已经都超过一个月了。因为对工作内容不是很满意&#xff0c;所以打算月底离职&#xff0c;也不知道是公司太缺人还是我真的能干活&#xff0c;领导竟然三番两次找我让我再考虑...明天又要找我了&#xff0c;哎...随机应变吧…

MySQL 索引 与 事务

简介 1索引及分类2创建及查看索引3事务的概念及特点4事务的操作5总结 拓展&#xff1a; 在开始了解索引之前&#xff0c;得学会安装 MySQL 和它的一些基本的命令&#xff0c;可以看看之前的一片文章&#xff1a;MySQL安装与基本命令 索引及分类 1索引的概念&#xff1a; 什么是…

[Vue CLI 3] 如何自定义 js 的文件名

在前面的一篇文章filenameHashing使用和源码设计中我们介绍了&#xff0c;为什么会出现 filename hash 的文件名&#xff0c;而且 hash 的位数多是固定的 假设你需要自定义 js 的文件名&#xff0c;比如入口文件编译之后的&#xff0c;如何处理呢&#xff1f; chainWebpack: c…

骁龙芯片性能排行2020_鲁大师2019年度手机性能、芯片、AI性能以及流畅排行榜:这些榜单你怎么看?...

手机性能榜2019年&#xff0c;高通打破了常规升级方案&#xff0c;在下半年推出了骁龙855 Plus处理器&#xff0c;成为了旗舰手机的标配&#xff0c;华为也发布了麒麟990和麒麟990 5G两款SOC&#xff0c;让旗下的机型有了更多的选择。由于子品牌的加入&#xff0c;市场竞争更加…

python pth文件是什么_嫌python慢?来这里用pytorch C++前端推理模型

本文面向对象是立足于工业应用领域的AI学习者&#xff0c;希望学以致用的同学们可以深入看这篇文章&#xff0c;我一直认为学而不用就是搞八股文&#xff0c;现实中很多模型很fancy指标很溜但实际上是根本用不了的.很多时候python用来训练模型很方便的&#xff0c;但是用来推理…

三分钟入门Redux(Redux教程)

学习背景&#xff1a; 我最近在更新师兄之前用React写的项目&#xff0c;该项目中各组件的状态依赖关系非常复杂&#xff0c;为了便于管理组件的状态&#xff0c;师兄使用了Redux。我最近刚转React&#xff0c;此前没有用过Redux&#xff0c;借这个难得的机会&#xff0c;我学习…

字符串的切片操作与连接_Python中14个切片操作,你常用哪几个?

切片&#xff08;Slice&#xff09;是一个取部分元素的操作&#xff0c;是Python中特有的功能。它可以操作list、tuple、字符串。Python的切片非常灵活&#xff0c;一行代码就可以实现很多行循环才能完成的操作。切片操作的三个参数 [start: stop: step] &#xff0c;其中start…

spring中的统一异常处理

在具体的SSM项目开发中&#xff0c;由于Controller层为处于请求处理的最顶层&#xff0c;再往上就是框架代码的。因此&#xff0c;肯定需要在Controller捕获所有异常&#xff0c;并且做适当处理&#xff0c;返回给前端一个友好的错误码。 不过&#xff0c;Controller一多&#…

arraylist从大到小排序_十大经典排序算法最强总结(内含代码实现),建议收藏!...

点击上方“Java之间”&#xff0c;选择“置顶或者星标”你关注的就是我关心的&#xff01;来源&#xff1a;cnblogs.com/cndarren/p/11787368.html上一篇&#xff1a;ArrayList集合为什么不能使用foreach增删改01 算法分类 十种常见排序算法可以分为两大类&#xff1a;比较类…

ret和retf

ret指令用栈中的数据&#xff0c;修改IP的内容&#xff0c;从而实现近转移; retf指令用栈中的数据&#xff0c;修改CS和IP的内容&#xff0c;从而实现远转移。 CPU执行ret指令时&#xff0c;进行下面两步操作: (IP) ((ss)*16(sp))(sp)(sp)2CPU执行retf指令时&#xff0c;进行下…

opengl实现经纹理映射的旋转立方体_立方体纹理

立方体纹理就是包含6个2D纹理的纹理.6个纹理有序排列在立方体的6个面.其可以通过方向向量采样立方体纹理上的纹素.创建立方体贴图跟创建2D贴图一样,但是绑定到GL_TEXTURE_CUBE_MAP上.glGenTextures(1, &CubeMapID); glBindTexture(GL_TEXTURE_CUBE_MAP, CubeMapID);立方体纹…
最新文章