Realization of function compose and Coriolis

Time:2021-3-4

Function Coriolis

Sometimes there is a need like this

add(5)(2)(3)=10
add(2,5)(3)=10
add(1)(7,2)=10

add(1)(8)(1)()=10
add(7,1)(1)(1)()=10
add(4)(2,1)(1)(2)()=10


Two ways of writing by Ke Lihua

1、 If the number of parameters passed in satisfies the number of parameters to be executed, the function will be executed

function curry_(fn) {
 //Returns a new function judge with the receive parameter... Args
    return function judge(...arg) {
        if (arg.length >= fn.length) { 
                //Does the length of the parameter received by the new function meet the length of the function to be received
                return fn(...arg)
                      //To meet the requirements, execute the FN function and pass in the parameters of the new function
                } else {
                     //If it does not meet the requirements, the recursive ﹣ judge ﹣ function integrates the parameters passed by the next execution
                return function(...args) {
                    return judge(...args, ...arg)
             }
        }
    }
}

var curry_fn = curry_(function(a, b, c) {
    return a + b + c
});
console.log (curry_ FN (5) (2) (3),'finite parameter cophysics and chemistry ');
//10

ES6 simplification:
    const curry_ = fn =>judge = (...args) =>args.length === fn.length ?fn(...args) : (...arg) => judge(...args, ...arg)

2、 If the last parameter value of the passed in parameter is empty, the function will be executed

function curry_(fn) {
    return function judge(...arg) {
        //Returns a new function, where arg is [23,1], that is, curry_ FN the first parameter passed in
        return function(...args) {
            //Returns the function after each execution of the previous function, namely curry_ After FN (23, 1) is executed, args is 3, 4, 0
            if (!args.length) {
                //If the latter function has no arguments, it is (), then the function is executed
                return fn(...arg)
            } else {
                //If the parameter of the latter function exists, it will be recursive and stored in arg
                return judge(...args, ...arg);
            }
        }
    }
}

var curry_fn = curry_(function(...args) {
    return args.reduce((a, b) => a + b, 0)
});
console.log (curry_ FN (2,1) (3) (4) (),'finite parameter Coriolis');
//10

ES6 simplification:
    const adder_ = fn => judge = (...arg) => (...args) => !args.length ? fn(...arg) : judge(...arg, ...args)

Compose function

1. From right to left
2. And the execution result of the previous function is taken as the parameter of the next function
3. The first function is multi parameter, and the following functions are all one parameter
4. All functions are executed synchronously

let greeting = (...arg) => 'hello, ' +  arg.join ('') // first function (multi parameter)
let toUpper = str =>  str.toUpperCase () // second function
Let timing = STR = > '${STR} time = ${+ new date()}' // the third function

//Method 1. Reduce method

let compose = function(...func) {
    //If there is no function, compose is returned_ The first parameter in my function
    if (func.length == 0) {
        return function(arg) {
            return arg
        }
    }
    //If there is only one function, this function is returned
    if (func.length == 1) {
        return func[0]
    }
    //Returns the result of reduce processing
    return func.reduce((itemFn, callback) => {
        //The initial callback is the first function, greeting ()
        return function(...arg) {
            //Arg is the parameter of the final function returned by the receiving processing function, namely 'Jack', 'Smith', 'Wang'
            return itemFn(callback(...arg))
            //The first function takes multiple parameters, returns a value, takes the next function as a parameter, and finally outputs   
        }
    })
}

//ES6 version:
    let compose = (...funcs) => {
        if (funcs.length === 0) return arg => arg
        if (funcs.length === 1) return funcs[0]
        return funcs.reduce((a, b) => (...args) => a(b(...args)))
    }


//Method 2: slider recursion
let compose = (...args) => {
    var len = args.length
    //Record the number of functions we pass in
    var count = len - 1 
    //The cursor records the execution of the function and serves as the index of the function we are running
    var result 
    //As a result, each time the function is executed, it is passed down
    return function f1(...arg) {
        //Arg is the parameter of the final function returned by the receiving processing function, namely 'Jack', 'Smith', 'Wang'
        result = args[count](...arg)
        if (count <= 0) { 
        //When there is only one function
            count = len - 1
            return result
        } else {
        //Multiple functions, cursor movement, recursive execution
            count--
            return f1(result)
        }
    }
}

let fn = compose(timing, toUpper, greeting)
console.log(fn('jack', 'smith', 'wang'))