Javascript 功能性 composition/sequencing
Javascript functional composition/sequencing
我正在尝试通过练习来理解 Javascript 中的构图和“排序”概念:
Def. "composition" compose(f,g)(x) = f(g(x))
Def. "sequencing" sequence(f,g)(x) = g(f(x))
for more args 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
It seems that the second function in the sequence can't access the args
是的,这是正常的,也是意料之中的。根据你给出的定义,
sequence(f1, f1, f2)(1, 2, 5);
等同于
f2(f1(f1(1, 2, 5)));
当然,f2
和外部 f1
都不能访问传递给内部 f1
的参数。
仅对 return 单个值起作用。有两种方法可以通过多个 return 值扩充函数:
- return 像元组这样的数组
- 而不是 return调用延续
这是后者的一个有趣实现,它明确不适用于任何生产代码:
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)); // escape from the continuation
请注意,所有函数都是柯里化的,我使用了术语 pipe
,这是 JS 中反向函数组合的常用术语。
我正在尝试通过练习来理解 Javascript 中的构图和“排序”概念:
Def. "composition"
compose(f,g)(x) = f(g(x))
Def. "sequencing"
sequence(f,g)(x) = g(f(x))
for more argssequence(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
It seems that the second function in the sequence can't access the args
是的,这是正常的,也是意料之中的。根据你给出的定义,
sequence(f1, f1, f2)(1, 2, 5);
等同于
f2(f1(f1(1, 2, 5)));
当然,f2
和外部 f1
都不能访问传递给内部 f1
的参数。
仅对 return 单个值起作用。有两种方法可以通过多个 return 值扩充函数:
- return 像元组这样的数组
- 而不是 return调用延续
这是后者的一个有趣实现,它明确不适用于任何生产代码:
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)); // escape from the continuation
请注意,所有函数都是柯里化的,我使用了术语 pipe
,这是 JS 中反向函数组合的常用术语。