如何在 JS 中创建一个重用返回结果的可变参数高阶函数
How to create a variadic high-order function reusing the returned result in JS
假设我有数量不确定的函数 f,每个函数需要一个参数并返回一个结果。我应该如何编写一个函数 "execute" 将第一个参数作为数字,并将所有其他参数作为函数应用于每个前面函数的结果?
这是我的猜测:
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)。
感谢您的帮助!
您可以使用 Array#reduce
结果 returns,同时使用具有给定值的函数。
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);
两个函数的幺半群组合完全符合您的要求:它通过所有组合函数传播一个参数,与您的示例的不同之处在于所有结果稍后都由另一个幺半群组合组合:
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
假设我有数量不确定的函数 f,每个函数需要一个参数并返回一个结果。我应该如何编写一个函数 "execute" 将第一个参数作为数字,并将所有其他参数作为函数应用于每个前面函数的结果?
这是我的猜测:
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)。
感谢您的帮助!
您可以使用 Array#reduce
结果 returns,同时使用具有给定值的函数。
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);
两个函数的幺半群组合完全符合您的要求:它通过所有组合函数传播一个参数,与您的示例的不同之处在于所有结果稍后都由另一个幺半群组合组合:
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