美文网首页
JS函数式编程之柯里化

JS函数式编程之柯里化

作者: treeQQ | 来源:发表于2019-07-22 14:18 被阅读0次

JS函数式编程之柯里化

为什么要了解柯里化

柯里化是函数式编程必须要使用的. 这里我们就先介绍下什么是柯里化, 然后通过一个小例子体会柯里化的特点和使用方式.

什么是柯里化

curry 的概念很简单:只传递给函数一部分参数来调用它,让它返回一个函数去处
理剩下的参数。
你可以一次性地调用 curry 函数,也可以每次只传一个参数分多次调用。

[引自: js函数式编程指南]

小例子——两个数字相加函数的柯里化

// 非柯里化方式实现两个数相加的函数
function add(x, y) {
    return x + y;
}
// 调用方式
var result = add(1, 2); // => 3
// 柯里化上面的求和函数, 即将两个参数的add函数改成传一个参数的函数
function curryAdd(x) {    
    return function(y) {
        return x + y;
    }
}
// 调用方式
var result = curryAdd(1)(2); // => 3

我们看到非柯里化方式实现的函数调用时,需要传递两个参数, 但是柯里化后, 传递第一个参数返回了一个函数, 返回的函数, 参数是之前的函数的第二个参数. 这样就保证了每个函数调用都传递一个参数.

既然结果一样, 柯里化后有什么好处呢?

如果我们有这样一个需求, 那柯里化就会派上用场. 我需要计算每个人的工资, 工资由基本工资和绩效工资组成. 每个人的基本工资一样, 但是他们的绩效工资不一样.用非柯里化的函数计算如下

// 假设基本工资是5000
// 员工a 绩效工资2000
var salaryA = add(5000, 2000);
// 员工b 绩效工资3000
var salaryB = add(5000, 3000);

用柯里化后的函数计算如下

// 创建一个缓存了基本工资的相加计算函数
var curryAddedX = curryAdd(5000);
// 计算员工a的工资
var salaryA = curryAddeX(2000);
// 计算员工b的工资
var salaryB = curryAddedY(3000);

用了柯里化后的函数计算, 就可以避免每次都传递5000这个基本工资了. 好处就是

  1. 减少了代码量
  2. 不用担心本该固定的值手误写错(在这里就是基本工资的值)

小例子——利用已有函数筛选数组中满足条件的元素

已有一个函数

// 第一个参数, 是否包含的字符串, 第二个参数是被检测的字符串
function isContain(smallStr, str) {
    return str.indexOf(smallStr) !== -1;
}        

使用数组的filter方法, 与上面的函数配合, 筛选出包含指定字符串的字符串

var arr = ['dog', 'cat', 'how are you'];
// 将isContain函数柯里化
function curryIsContain(smallStr) {
    return function(str) {
        return str.indexOf(smallStr) !== -1;
    }
}
// 创建一个缓存了参数smallStr的筛选的函数, 用于筛选出含有空格的元素
var containSpace= curryIsContain(' ');
var result = arr.filter(containSpace);
// 创建一个用于筛选含有o的字符串
var containO = curryIsContain('o');
result = arr.filter(containO);                              

我们发现我们这里从新写了一个curryIsContain方法.

其实是用通用的办法把isContain转换成curryIsContain的.

这个办法就是: 柯里化函数. 我们来实现下他

// fn参数为将要被柯里化的函数, srcArgs参数为之前缓存的参数
function curry(fn, srcArgs) {
    return function() {
        var args = [].slice.apply(arguments);
        var fullArgs = srcArgs === undefined ? args : srcArgs.concat(args);
        if(fullArgs.length >= fn.length) {
            return fn.apply(null, fullArgs);
        } else {
            return curry(fn, fullArgs);
        }
    }
}

我们用我们这个柯里化函数把isContain转换为curryIsContain

// 通过curry转换的curryIsContain具有同样的使用方式
var curryIsContain = curry(isContain);

提供柯里化的开源框架

ramda

lodash

总结

柯里化的函数, 拥有暂存部分参数, 延迟执行的能力. 直至所有的参数都提供完才执行有效功能代码.

如果我们刚好有个可用的多参函数FucntionMutiParams.

恰好另外一个地方, 需要使用函数FucntionMutiParams.

但是部分参数已经固定不需要改, 比如第一个例子中的固定工资.

或者有的地方只需要一个参数的函数. 事实上函数式编程的另外一个操作组合函数, 就需要只有一个参数的函数.

后面我们学习组合函数, 就会理解柯里化的必要性.

相关文章

  • JS函数式编程之柯里化

    JS函数式编程之柯里化 为什么要了解柯里化 柯里化是函数式编程必须要使用的. 这里我们就先介绍下什么是柯里化, 然...

  • js 函数式编程之柯里化

    将使用多个参数的函数转换成一系列使用一个参数的函数的技术。 主要用途是可以简化代码结构, 提高系统的可维护性, 一...

  • [译]JavaScript中的函数柯里化

    原文 Currying in JS 函数柯里化 函数柯里化以Haskell Brooks Curry命名,柯里化是...

  • 函数式编程

    1 文章目标 为什么要学习函数式编程以及什么是函数式编程 函数式编程的特性(纯函数、柯里化、函数组合等) 函数式编...

  • js柯里化

    标签: js柯里化 js柯里化 柯里化是什么在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成...

  • 猫眼

    var变量提升,函数声明提升,消除变量声明提升(let); 高阶函数,函数式的编程,柯里化 原型链继承,js面向对...

  • JS_函数柯里化

    JS_函数柯里化 与函数绑定密切相关的主体是函数柯里化(function currying),它用于创建已经设置好...

  • 函数式编程(三)—— 柯里化

    柯里化Lodash中的柯里化 —— curry()案例柯里化原理模拟柯里化总结 【函数式编程总体设计】 之前讲了函...

  • Swift函数式编程与面向协议编程

    函数式编程(FP) 一、函数式编程(FP)-高阶函数 二、函数式编程(FP) - 柯里化(Currying) 三、...

  • Swift Currying(柯里化)

    Swift Currying(柯里化) 标签(空格分隔): swift 函数式编程思想先举一个小例子: 显然这种编...

网友评论

      本文标题:JS函数式编程之柯里化

      本文链接:https://www.haomeiwen.com/subject/wynblctx.html