我正在尝试通过练习来理解Javascript中的组成和“排序”概念:
Def。 “组成”
compose(f,g)(x) = f(g(x))
Def。 “排序”
sequence(f,g)(x) = g(f(x))
获得更多的参数sequence(f,g)(...args) = g(f(...args))
const sequence2 = (f1, f2) => (...args) => f2( f1(...args) );
const sequence = (f1, ...fRest) => fRest.reduce(sequence2, f1);
const f1 = (a, b) => {
console.log(`[f1] working on: ${a} and ${b}`);
return a + b;
}
const f2 = a => `Result is ${a}`;
const sequenceResult = sequence(f1, f1, f2)(1, 2, 5);
console.log(sequenceResult);
控制台显示:
[f1] working on: 1 and 2
[f1] working on: 3 and undefined
Result is NaN
似乎序列中的第二个函数无法访问args:我缺少某些东西,或者这是处理参数的错误方法? (序列函数适用于不带参数的函数)。
这里JSFiddle
似乎序列中的第二个函数无法访问参数
是的,这是正常现象,符合预期。根据您给的定义,
sequence(f1, f1, f2)(1, 2, 5);
相当于
f2(f1(f1(1, 2, 5)));
当然f2
和外部f1
都不能访问传递给内部f1
的参数。
函数仅返回单个值。有两种通过多个返回值扩展功能的方法:
这是后者的一个有趣的实现,这显然并不意味着任何生产代码:
const pipek = g => f => x => y => k =>
k(g(x) (y) (f));
const addk = x => y => k =>
(console.log("apply addk to", x, y), k(x + y));
const main = pipek(addk)
(addk)
(2)
(3)
(k => k(4)); // we have to pass the 4th argument within the continuation
console.log(main(x => x));
[请注意,所有函数都是库里函数,并且我使用术语pipe
,这是JS中反向函数组合的常用术语。