跳到主要内容

函数组合风格

函数组合怎样把小步骤连接起来?​

  • 组合: 把一个函数的输出交给另一个函数,形成第三个函数;
  • 数据流: compose(f, g)(a) 等于 f(g(a));
const compose = (f, g) => (a) => f(g(a));
const floorAndToString = compose(String, Math.floor);
floorAndToString(121.212121); // '121'

Point-Free 风格为什么不写数据参数?​

  • Point-Free / Tacit: 定义中不显式写出被处理的数据参数;
  • 前提: 常借助柯里化、高阶函数和组合,先描述变换本身;
const map = (fn) => (list) => list.map(fn);
const add = (a) => (b) => a + b;

const incrementAll = (numbers) => map(add(1))(numbers);
const incrementAllPointFree = map(add(1));
  • 取舍: 简单管道更紧凑;层层组合后若难读,应保留显式参数;

函数组合子怎样改造其他函数?​

  • 组合子: 通常为柯里化高阶函数,接收函数并返回经过某种改造的新函数;
  • 用途: 在 Point-Free 程序中复用参数交换、应用和组合模式;
const C = (fn) => (a) => (b) => fn(b)(a);
const divide = (a) => (b) => a / b;
const divideBy = C(divide);
const divBy10 = divideBy(10);

divBy10(30); // 3
  • C 组合子: 交换柯里化二元函数的参数顺序;