Reputation: 12281
I have a curried function which I am using in a composition and this works:
const getClubs = R.filter(R.propEq('suit', 'CLUBS'))
This is taking in an array of card objects and filtering them by their suit.
But when I try to unnest this function call and turn it into a pipe:
const getClubs = R.pipe(R.filter, R.propEq('suit', 'CLUBS'))
...this doesn't work anymore and I don't even get any errors. What am I doing wrong with my pipe or filter functions?
Here is a working version of my code
Toggle between line no.8 and line no.9 to see the problem I am describing above
Upvotes: 1
Views: 2002
Reputation: 50807
This has at least two problems. First, you're confusing compose
and pipe
. They are very similar, but they apply their functions in the opposite order.
pipe(g, f)(x); //=> f(g(x))
compose(g, f)(x); //=> g(f(x))
So if you want an equivalent of filter(propEq('suit', 'CLUBS'))
, then you need to write one of the following instead of R.pipe(R.filter, R.propEq('suit', 'CLUBS'))
:
R.pipe(R.propEq('suit', 'CLUBS'), R.filter)
// or
R.compose(R.filter, R.propEq('suit', 'CLUBS'))
But the second problem is more fundamental. pipe
and compose
do not pass one item of their list of function to another one. Instead, they return functions in which the first function is called against the data supplied, the second one is called against the result of the first, the third is called against the result of the second, the fourth against the result of the third, etc.
But filter
needs two parameters, a predicate function and a list of values.
Your filter(propEq('suit', 'CLUBS'))
is passing filter(propEq('suit', 'CLUBS'))
, a function of one argument due to currying, to filter
, which needs a one-argument function and a list of values. Because we pass just the first, we get back a function that takes the list of values and filters it down to the matching ones.
When you try, say pipe(propEq('suit', 'CLUBS'), filter)
, and call the resulting function with a list called cards
, you pass cards
to propEq('suit', 'CARDS')
, and since cards
is a list without a suit
property, it returns false. You then call filter
with this false
value. Since this curried function requires two parameters, you get back a function looking for a second parameter. It's a useless function, though, because the first argument, false
is not a predicate function.
I hope that makes sense. I didn't get much sleep last night, and I'm not quite sure what's sensible. :-)
Upvotes: 5