如果我有一堆严格链接在一起的函数,那么使用 compose
来组合它们就很容易了:
f1 : A -> B
f2 : B -> C
f3 : C -> D
pipe(f1, f2, f3) : A -> D
我常常发现事情并不是那么完美,并且在稍后阶段再次需要 A
中包含的信息:
f1 : A -> B
f2 : B -> C
f3 : (A, C) -> D
如何优雅地组合这些函数?我觉得我想要某种“隐藏”将 A
塞进一对或其他东西中,将 pipe(f1,f2)
映射到第二个元素上,然后我有一切准备就绪,等待f3
。不过,我无法想出一种非常优雅的方法来做到这一点,而且感觉这是一种很常见的情况,必须有一个既定的模式!
作为一个具体的例子,假设我有一个字符串,如果它的长度为偶数,我想返回它,否则我想返回none
。
f1 = len
f2 = mod(2)
f3 = (s, m) => m == 0 ? Just(s) : None
如何将它们组合在一起?
最佳答案
函数组合的类型不允许这样做。我认为 lambda 和柯里化(Currying)比通过组合传递元组类型更简单、更明确:
const f1 = s => s.length;
const f2 = n => n % 2;
const f3 = s => m => m === 0 ? s : null;
const comp3 = f => g => h => x => f(g(h(x)));
const main = s => comp3(f3(s)) (f2) (f1) (s);
console.log(main("hallo"));
console.log(main("halloo"));
如果你绝对想要它自由,你也可以利用函数组合可能产生另一个函数的事实:
const f1 = s => s.length;
const f2 = n => n % 2;
const f3 = s => m => m === 0 ? s : null;
const comp3 = f => g => h => x => f(g(h(x)));
const join = f => x => f(x) (x); // monadic join
const flip = f => y => x => f(x) (y);
const main = join(comp3(flip(f3)) (f2) (f1));
console.log(main("hallo"));
console.log(main("halloo"));
虽然很难阅读。
关于functional-programming - 如何将数据传递到撰写管道的后续阶段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59084091/