假设我有一堆arity 2的函数:f: a b -> x
,g: c d -> y
,
等到一元函数u: a -> a
。我想做的是以这种方式链接它们:
f(_, g(_, .... z(_, u(_))...)
其中内部_
占位符将注入来自给定输入数组的连续值。我试图使用Ramda
库解决此问题。
我遇到的另一个非常类似的问题是以相同的方式链接函数,但_
占位符填充了与此合成执行相同的值。
更具体一点:
// 1st problem
someComposition( f(v[0], g(v[1], ..... z(v[n-1], u(v[n]))...) )(v);
// 2nd problem
someComposition2( f(v, g(v, ..... z(v, u(v))...) )(v);
我能想出的第二个问题是,假设所有函数都是可以修改的,遵循一段代码(因为(v)
重复而讨厌它):
compose(
z(v),
...
g(v),
f(v),
u
)(v);
我尝试使用compose
,composeK
,pipe
,ap
解决问题,但似乎没有一个适用于这种情况,或者我只是无法看到解决方案。任何帮助都更受欢迎。
答案 0 :(得分:1)
可能有一些我不知道的方便的Ramda功能,或者一些超级功能的组合 - 我不明白这使得这很容易,但无论如何:
您可以创建自己的合成函数来组合二进制函数列表并注入值。此函数采用函数列表和参数列表。它部分地应用它获得的第一个函数到第一个参数并继续这样做,直到它超出参数,在该参数下它返回一个最终的组合(一元)函数:
// Utils
const { add, subtract, multiply, identity, compose, isNil } = R;
const square = x => x * x;
// Our own compose method
const comp2_1 = ([f2, ...f2s ], [x, ...xs], f = identity) =>
isNil(x)
? compose(f2, f)
: comp2_1(f2s, xs, compose(f2(x), f));
// An example
const myFormula = comp2_1(
[add, subtract, multiply, square],
[10, 5, 2]);
// 3 + 10 = 13
// 13 - 5 = 8
// 8 * 2 = 16
// 16 * 16 = 256
console.log(myFormula(3));
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
此示例仅适用于xs.length === fs.length + 1
。例如,即使我们没有参数,你也可能希望它更灵活一些:
/* ... */
isNil(x)
? isNil(f2)
? f
: comp2_1(f2s, [], compose(f2, f))
: /* ... */
答案 1 :(得分:1)
Ramda中没有任何内容可以直接用于其中任何一个。 (免责声明:我是Ramda的作者之一。)如果你愿意,你可以创建这样的组合函数:
const {tail, compose, reduce, identity, reverse} = R;
const f = (x, y) => `f(${x}, ${y})`;
const g = (x, y) => `g(${x}, ${y})`;
const h = (x, y) => `h(${x}, ${y})`;
const i = (x, y) => `i(${x}, ${y})`;
const j = (x) => `j(${x})`;
const multApply = (fns) => (...vals) => fns.length < 2
? fns[0].apply(null, vals)
: fns[0](vals[0], multApply(tail(fns))(...tail(vals)));
console.log(multApply([f, g, h, i, j])('a', 'b', 'c', 'd', 'e'));
//=> f(a, g(b, h(c, i(d, j(e)))))
const nest = compose(reduce((g, f) => (v) => f(v, g(v)), identity), reverse);
console.log(nest([f, g, h, i, j])('v')) //=> f(v, g(v, h(v, i(v, j(v)))));
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
这些都没有对空列表进行任何错误检查,或者对于比功能列表短的参数列表(在第一种情况下)。但除此之外,它们似乎符合要求。
肯定会有第二个的递归版本与第一个相匹配,但这个实现已经非常简单了。我没有看到第一个版本和第二个版本一样简单,但它可能存在。