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

news/2024/11/9 17:36:09

何为柯里化

概念:在计算机科学中,柯里化(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…