functional-programming - 如何将数据传递到撰写管道的后续阶段

标签 functional-programming

如果我有一堆严格链接在一起的函数,那么使用 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/

相关文章:

f# - 如何在 F# 类中定义和使用静态变量

list - 无法将预期类型 `[Integer]' 与实际类型 `Bool' 匹配

javascript - Array.includes 的功能使用会导致 TypeError

F# 中 ||> 和 |||> 管道运算符的性能影响

variables - 为什么不能像Java中那样在内联函数中正确初始化变量?

javascript - 在 Javascript 中,为什么实例或对象文字没有 "prototype"属性?

database - 我应该用不可变或可变数据结构表示数据库数据吗?

scala - 学习 Scala 作为第一个 'functional' 语言?

javascript - javascript/nodejs 中的函数式思维

clojure - 函数式编程中的条件 "assignment"