函数式编程(三)

前面两节引见了纯函数和高阶函数,在函数式编程中,函数就是我们的砖块。我们编写一些能够完成异常详细任务的函数,然后像乐高积木一样将他们搭建起来。

这就是所谓的函数组合。

函数组合

先看两个纯函数

let add10 = value => value + 10;
let mult5 = value => value * 5;

let mult5AfterAdd10 = value => mult5(add10(value)) 

如许写代码很轻易写出h(g(f(e(x)))),如许层层相套的代码,一层一层扒开它的心。
为相识函数嵌套的问题,我们能够先预定义一个组合函数

var compose = function(f,g) {
  return function(x) {
    return f(g(x));
  };
};

然后改写上面的例子

let mult5AfterAdd10 = compose(mult5, add10)
mult5AfterAdd10(5)

如许做的可读性远远高于嵌套一大堆的函数挪用。

Point Free

把一些对象自带的要领转化为纯函数,不要定名转瞬即逝的中心变量

网上有许多关于Point Free的案例,我认为都不怎样能申明问题,下面这个例子是我经心预备的秘要,平常不别传。

const f = str => str.toUpperCase().split('');
const toUpperCase = word => word.toUpperCase();
const split = x => (str => str.split(x));


const f = compose(split(''), toUpperCase)

f("aa vv")
//我们没有运用到str变量

我们不须要指定冗余的参数。由于没必要指定参数,所以也就没必要斟酌为它们定名。其次,由于更简短使得更轻易浏览。Pointfree 的实质就是运用一些通用的函数,组合出种种庞杂运算。上层运算不要直接操纵数据,而是经由过程底层函数去处置惩罚。这就请求,将一些经常使用的操纵封装成函数。所以说这类体式格局慎用。

看到这里你是否是认为本身就相识函数式编程了呢?nonono?下面我有个问题想考考你。

let add = (value, y) => value + y;
let mult5 = value => value * 5;

我想改写上面的mult5AfterAdd10函数,把它转成更通用的mult5AfterAdd,你想到用上面学到的姿态,

let mult5AfterAdd = compose(mult5, add) 

明显这个不可的,由于add函数须要吸收两个参数,现实只通报了一个参数,所以它会将一个毛病的效果通报给mult5。这最终会发生一个毛病的效果。
我们怎样处理这个问题?事实证明有一种要领,它就是柯里化(Currying)

下面我们来看看函数的柯里化。
有如许一道问题,完成一个函数,完成以下功用:

var result = sum(1)(2)(3);
console.log(result);//6

以下是一种完成体式格局

function add(a){
    var sum = 0;
        sum += a;
    return b => {
        sum += b;
        return c => {
            sum += c;
            return sum;
        }
    }
}
add(1)(2)(3);//6

我们来处理上面遗留的问题,经由过程改写add函数

let add = x => y => x + y
let compose = (f, g) => x => f(g(x));
let mult5AfterAdd10 = compose(mult5, add(10));

我们就是将简朴罕见的add函数转化成了柯里化函数,如许add函数就变得越发自在灵活了。我们先将第1个参数10输入,而当mult5AfterAdd10函数被挪用的时刻,末了1个参数才有了肯定的值。

柯里化

柯里化一般也称部份求值,其寄义是给函数分步通报参数,每次通报参数后,部份运用参数,并返回一个更详细的函数接收剩下的参数,中心可嵌套多层如许的接收部份参数函数,逐渐减少函数的适用范围,逐渐求解,直至返回末了效果。

一个简朴的通用模块的函数柯里化封装

const curry = fn => {
    const _args = [];
    return function cb() {

        if(arguments.length === 0) {
            return fn.apply(this, _args);
        }

        Array.prototype.push.apply(_args, [...arguments]);

        return cb;
    }
}


函数柯里化是一种预加载函数的要领,经由过程通报较少的参数,获得一个已记住了这些参数的新函数,某种意义上来说,这是一种对参数的“缓存”,是一种异常高效的编写函数的要领。⚠️参数递次是可否最大水平应用柯里化的关键所在。

    原文作者:林小新
    原文地址: https://segmentfault.com/a/1190000009324745
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞