函数式编程 (二) 柯里化和组合函数

44 阅读2分钟

柯里化函数

柯里化函数就是函数一次只允许传入一个参数 , 比如 原本的函数是 fn(1,2,3),经过柯里化之后的函数 值 fn(1)(2)(3)

与偏函数的区别是?

偏函数和柯里化函数类似, 但是偏函数, 可以传入好几个参数 , 最后当参数传齐了之后只执行。

柯里化函数有什么作用

当一个函数中每次一个函数的参数有固定的几种的话, 为了少写几次 , 我们就可以用函数柯里化来生成函数 , 减少传参。 如:

 function isType(type, val) {
  return Object.prototype.toString.call(val)===`[object ${type}]`}

这里的type的取值有String, Number,Object, Array等等 , 这个时候我们就可以用柯里化函数生成对应的几种方法:

const iString =  ccurry(isType)("String")
const isNumber = curry(isType)
isString("123")

如何实现函数柯里化?

函数柯里化的本质就是等参数凑齐了再整, 所以可以搞一个变量形成闭包,利用递归来实现。具体的实现方法是:

function curry (fn) {
    function curried  (...args) {
    if(args.length>=fn.length){
        fn(...args)}
    }else{
     return (...rest) => {
         curried(...args,...rest)
     }}
    return curried
}

组合函数

所谓的组合函数就是让一个函数的返回值作为另一个函数的参数, 依次执行。 比如fn1(fn2(fn3(num)))将它组合成一个新的函数然后执行,有点类似于redux里面组合中间件的那个函数。 如果现在我们现在想实现一个数字* 2 然后+2 —1 ,我们会怎么实现呢?

利用函数的单一原则 , 我们可以先写上三个函数

    function double(num){
        return num *2
    }
    function minus1 (num){
        return num  -1
    }
    function add2(num){
    return num +2
    }

实现过程是minus1(add2(double(num)))

如果我们使用了组合函数

const compute = compose(...[double, add2, minus1])
compute(num)

如何实现compose函数呢?

我们可以使用arr的自带方法reduceRight 和reduce, 具体看我们传入函数的顺序 ,实现函数的组合

function compose (...fns) {
return  fns.reduceRight((fn1, fn2) => {
 return (...args) => {
     return  fn1(fn2(...args))
 }
 })
}