【问题标题】:How to create a variadic high-order function reusing the returned result in JS如何在 JS 中重用返回的结果创建可变参数高阶函数
【发布时间】:2017-05-24 08:49:11
【问题描述】:

假设我有一个未确定数量的函数 f,每个函数都需要一个参数并返回一个结果。我应该如何编写一个函数“执行”,将第一个参数作为数字,将所有其他参数作为函数应用于每个前面函数的结果?

这是我的猜测:

let plus1 = d => d += 1;
let plus2 = d => d += 2;
let write = d => document.write(d);


let execute = function(n,...functions){
  functions.forEach((d)=>d(n));
}

execute(4,plus1,plus2,write); 

我期待 7 ((4+1)+2)。

感谢您的帮助!

【问题讨论】:

    标签: javascript function variadic


    【解决方案1】:

    两个函数的幺半群组合完全符合您的要求:它通过所有组合函数传播一个参数,与您的示例不同的是,所有结果稍后都由另一个幺半群组合组合:

    function monoidCombine(f, g) {
      let ftype = typeof f;
      let gtype = typeof g;
      if (ftype === "function" && gtype === "function") {
        return function(input) {
          return monoidCombine(f(input), g(input));
        };
      }
    
      if (ftype === "number" && gtype === "number") {
        return f + g;
      }
    
      throw new Error(`No case for monoidCombine(${ftype}, ${gtype})`);
    }
    
    function execute(n, ...functions) {
      return functions.reduce((f, g) => monoidCombine(f, g))(n);
    }
    
    execute(1, (x) => x + 3, (x) => x + 1);  
    // ^-- is equivalent to ((x) => x + 3)(1) + ((x) => x + 1)(1)
    // so the result is 6

    【讨论】:

      【解决方案2】:

      你可以使用Array#reduce,它返回一个结果,同时使用一个给定值的函数。

      let plus1 = d => d + 1,
          plus2 = d => d + 2,
          write = d => console.log(d),
          execute = (n, ...fn) => fn.reduce((n, f) => f(n), n);
      
      execute(4, plus1, plus2, write); 

      Yury Tarabanko 建议的较短版本

      let plus1 = d => d + 1,
          plus2 = d => d + 2,
          write = d => console.log(d),
          execute = (...args) => args.reduce((v, f) => f(v));
      
      execute(4, plus1, plus2, write); 

      【讨论】:

      • 可以是let execute = (...fn) => fn.reduce((n, f) => f(n));
      • @YuryTarabanko 最好不要养成忽略初始累加器值的习惯。此外,fn 的名称也不再准确,因为它现在是一个具有一个数字和功能的异构数组。
      • @Bergi 为什么?这种多态行为在文档中得到了完美的说明。我有点喜欢它检查我的数组是否有值。除了您的个人喜好之外还有什么原因吗?
      • @YuryTarabanko 客观地说,它是类型更好、更清洁、更易于维护的代码。但是,是的,使用它归结为对函数式编程的偏好。
      • @Bergi 我希望有reduce1 (fold11) 但规范作者决定采用另一种方法。客观地说,我对函数式编程的偏好与你不同。 :)
      猜你喜欢
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 2015-07-04
      相关资源
      最近更新 更多