【fp】函数式编程入门 柯里化、compose、pipe

82 阅读2分钟
/*--------------------------------------- 高阶函数 ------------------------------------------*/
// 高阶函数是指接受函数作为参数或者返回一个函数的函数。
// 1. 函数作为参数
// 2. 函数作为返回值
// 3. 函数作为参数和返回值

const count = (func) => {
  let count = 0;

  return [
    (...args) => {
      count++;
      func(...args);
    },
    () => {
      console.log(`执行了${count}次`);
    },
  ];
};

const [add, getCount] = count(() => console.log("add"));

add();
add();
add();
add();
add();
add();
add();
add();
getCount(); // 执行了8次
/*--------------------------------------- 传送带模型 ------------------------------------------*/

// 传送带模型 reduces用法
const conveyorFunc = (...func) => {
  return func.reduce(
    (prev, cur) => {
      return (input) => {
        return cur(prev(input));
      };
    },
    (input) => input
  );
};

//+5
//-3
//+10
//+2
//*3
// /2

const conveyorModel = conveyorFunc(
  (input) => input + 5,
  (input) => input - 3,
  (input) => input + 10,
  (input) => input + 2,
  (input) => input * 3,
  (input) => input / 2
);
console.log(conveyorModel(1)); // 22.5

/*--------------------------------------- 部分应用函数/柯里化 ------------------------------------------*/
//科里化是将一个多参数函数转换为一系列单参数函数的过程
//部分应用是指固定一个函数的一个或
//多个参数,然后生成另一个函数的过程
//柯里化是部分应用的一个特例
//柯里化的目标是使函数参数降维

//curyfunc
const curyFunc = (func, args = []) => {
  return (input) => {
    const newArgs = args.concat(input);
    if (newArgs.length >= func.length) {
      return func(...newArgs);
    } else {
      return curyFunc(func, newArgs);
    }
  };
};

const add = (a, b, c, d) => a + b + c + d;
const curyAdd = curyFunc(add);
console.log(curyAdd(1)(2)(3)(4)); // 10

/*--------------------------------------- pipe/compose ------------------------------------------*/
//pipe函数作用
//pipe函数接受任意数量的函数作为参数,然后返回一个新函数,这个新函数会依次执行每一个参数函数,并将前一个函数的返回值传递给下一个函数。
//compose函数作用
//compose函数接受任意数量的函数作为参数,然后返回一个新函数,这个新函数会依次执行每一个参数函数,但是是从右往左执行。

//pipe函数
const pipe =
  (...fns) =>
  (x) =>
    fns.reduce((v, f) => f(v), x);
//compose函数
const compose =
  (...fns) =>
  (x) =>
    fns.reduceRight((v, f) => f(v), x);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const subtract = (x) => x - 3;
const divide = (x) => x / 4;
const addThenMultiply = pipe(add, multiply);
const subtractThenDivide = compose(subtract, divide);
console.log(addThenMultiply(1)); // 4
console.log(subtractThenDivide(1)); // -2.75