函数柯里化和偏函数应用

什么是函数柯里化(Currying)


维基百科中的定义:bash

在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,而且返回接受余下的参数并且返回结果的新函数的技术。闭包

换句话说就是把一个有n个参数的函数转换成n个嵌套的函数,每一个函数只接受一个参数,并返回一个新函数。也就是把f(a,b,c)转化为f(a)(b)(c)函数

 

例子


例如一个函数接受a, b, c三个参数,返回它们的乘积:ui

function multiply(a, b, c) {
    return a * b * c;
}
复制代码

运行此函数,咱们在参数中依次传入1,2,3,返回6。this

multiply(1,2,3); // 6

复制代码

让咱们看一下柯里化以后的样子:spa

function multiply(a) {
    return (b) => {
        return (c) => {
            return a * b * c
        }
    }
}
multiply(1)(2)(3) // 6
复制代码

咱们把multiply(1,2,3)变成了multiply(1)(2)(3)的形式。经过把一个多参函数转换成一系列嵌套的函数,每一个函数依次接受一个参数,这就是函数柯里化。code

或者换一种写法能够更容易理解:ip

function multiply(a) {
    return (b) => {
        return (c) => {
            return a * b * c
        }
    }
}
const mul1 = multiply(1);
const mul2 = mul1(2);
const result = mul2(3);  // 6
复制代码

multiply函数接受一个a参数,咱们传入1。mult1等于multiply(1)就等于it

(b) => {
    return (c) => {
        return a * b * c
    }
}
复制代码

而且接受一个参数b。以此类推,mul1(2)传入2,而后赋值给mult2等于io

(c) => {
    return a * b * c
}
复制代码

最后mul2(3)返回a * b * c。因为闭包的特性会保存以前传入的值1和2,最后得出6。

 

函数柯里化的应用


  • 柯里化函数避免咱们重复传参,实现复用

假设咱们有一个函数用来计算三个物体的体积。

function volume(l, w, h) {
    return l * w * h;
}
volume(200,30,100) // 2003000
volume(32,45,100); //144000
volume(2322,232,100) // 53870400
复制代码

从上面代码能够看出,若是每一个物体的高度都是100,咱们须要重复传三次。 若是使用柯里化函数能够避免:

function volume(h) {
    return (w) => {
        return (l) => {
            return l * w * h
        }
    }
}

//固定高度
const itemHeight = volume(100);

//计算其余不一样状况
itemHeight(30)(200); 
itemHeight(45)(32); 
itemHeight(232)(2322); 
复制代码
  • 函数的合成

合成两个函数的简单代码以下:

var compose = function(f,g) {
  return function(x) {
    return f(g(x));
  };
};
复制代码

f(x)g(x)合成为f(g(x)),有一个隐藏的前提,就是f和g都只能接受一个参数, 其中就运用了函数柯里化。

 

什么是偏函数应用(Partial Application)


Partial Application(偏函数应用)很容易和函数柯里化混淆,它是指使用一个函数并将其应用一个或多个参数,但不是所有参数,在这个过程当中建立一个新函数,这个函数用于接受剩余的参数。这段话很不容易理解,具体看下面的例子:

 

例子


function multiply(a,b,c){
    return a * b * c;
}
//生产偏函数的工厂
function partial(fn,a){
    return function(b,c){
        return fn(a,b,c);
    }
}

//变量parMulti接受返回的新函数
var parMulti = partial(multiply,1);

//在调用的时候传入剩余的参数
parMulti(2,3); // 6
复制代码
  1. partial函数能够帮咱们生成一个偏函数。
  2. 调用partial函数生成一个偏函数并赋值给parMulti,其中预设一个值1
  3. parMulti接受剩余参数2,3结合前面预设的1得出最终结果。

 

偏函数的应用


例如bind函数可让咱们传入一个或多个想要预设的参数,以后返回一个新函数,并拥有指定的this值和预设参数。当绑定函数被调用时,这些参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。

function addition(x, y) {
   return x + y;
}
const plus5 = addition.bind(null, 5)
plus5(10) // output -> 15
plus5(20) // output -> 25
复制代码

咱们预先传入了参数5,并返回了一个新函数赋值给plus5,此函数能够接受剩余的参数。调用plus5传入剩余参数10得出最终结果15,如传入20得出25。偏函数经过设定预设值,帮咱们实现代码上的复用。

 

总结


柯里化和偏函数都是用于将多个参数函数,转化为接受更少参数函数的方法。传入部分参数后,处于中间状态的函数能够做为固定值进行复用。可是其中不一样之处在于:

  • 柯里化是将函数转化为多个嵌套的一元函数,也就是每一个函数只接受一个参数。
  • 偏函数能够接受不仅一个参数,它被固定了部分参数做为预设,并能够接受剩余的参数。
相关文章
相关标签/搜索