在Ramda管道中使用相同的第一个参数

问题描述:

是否可以在Ramda中组合以下函数?在Ramda管道中使用相同的第一个参数

(a, b) => R.pipe(func1(a), func2(a))(b)

目的是通过参数a所有功能在pipe

我最初的想法是以下几点:

R.pipe(R.juxt([func1, func2]), R.apply(R.pipe))

但是这给TypeError: Cannot read property 'length' of undefined

这是更容易使用S.pipe来表达,因为它需要的功能来构成一个阵列

一种选择是使用R.ap

> S.pipe(R.ap([S.add, S.mult, S.add], [3]), 10) 
42 

另一种选择是使用R.mapS.T,画眉组合子:

> S.pipe(R.map(S.T(3), [S.add, S.mult, S.add]), 10) 
42 

然后,您可以包装的其中之一的拉姆达创建一个二进制函数:

const f = (a, b) => S.pipe(R.ap([S.add, S.mult, S.add], [a]), b); 

f(3, 10); // add(3)(mult(3)(add(3)(10))) 
// => 42 
+0

谢谢,我的答案来自你的回答:'R.pipe(R.of,R.ap([R.assoc('b'),R.assoc('c')]),R.apply(R.pipe ))(2)({a:1})// = {a:1,b:2,c:2}' – MattMS

你必须创建的所有功能的咖喱版本,然后调用每个咖喱版本a终于在任一R.pipeR.reduce

使用b假设需要的功能有a作为第一个参数是f,g,h(在特定的顺序),那么我们要做到以下表达式

h(a, g(a, f(a, b))) 

第一都让我们创建一个令行禁止函数接收两个参数,一个值v和功能fn,当这个函数接收所有必需的参数,将简单的返回fn(v)

const rev = R.curry((v, fn) => fn(v)) 

接下来我们可以创建的的咖喱版本与R.mapR.curry

// note the reversed order of the functions 
// I'll use R.compose instead of R.pipe 
let curriedVersion = R.map(R.curry, [h,g,f]) 

然而,我们还需要使用a作为的咖喱函数的第一个参数的功能,我们可以用调用每个令行禁止功能与aR.map而是我们将用我们的特殊功能rev

const curriedVersion = R.map(R.compose(rev(a), R.curry), [h,g,f]) 

最后让我们用这个阵的咖喱功能与R.composeb

const result = R.compose.apply(undefined, curriedVersion)(b) 

一个衬垫(用于在特定顺序的功能f,g,h):

const solver = (a, b) => R.compose.apply(undefined, R.map(R.compose(rev(a), R.curry), [h,g,f]))(b) 

const add = (a, b) => a + b 
 
const sub = (a, b) => a - b 
 
const mul = (a, b) => a * b 
 

 
const rev = R.curry((v, fn) => fn(v)) 
 
const solver = (a, b) => R.compose.apply(undefined, R.map(R.compose(rev(a), R.curry), [mul,sub,add]))(b) 
 

 
// mul(2, sub(2, add(2, 3))) 
 
// mul(2, sub(2, 5)) 
 
// mul(2, -3) 
 
// -6 
 
console.log(solver(2, 3))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.21.0/ramda.min.js"></script>

+0

我建议使用['R.apply '](http://ramdajs.com/docs/#apply)而不是'R.compose.apply(undefined,...)'。 – davidchambers

+0

@davidchambers感谢您的建议! –