1

I would like to call an Array of functions with a value and get an Array of the partially applied functions back.

My current code:

const my_array = pipe(flip(call), flip(map)([add, subtract]))(1)
// = [add(1), subtract(1)]

Is there a better way of doing this?

My goal (possibly unreasonable) would be to have a point-free alternative to the following function:

const bind_all = (funcs) => pipe(flip(call), flip(map)(funcs))
bind_all([add, subtract])(1)
// = [add(1), subtract(1)]

This seems to be similar to juxt, but returning an Array instead of a function.


Update: In response to the answers, I agree that my current code is far from readable, due to trying to force a point-free approach (with limited knowledge of existing patterns). This question is simply trying to explore the limits of point-free design that maintains readability.

The current answers seem to indicate that this is actually unreasonable.

2 Answers 2

2

Maybe I'm missing something, but juxt does seem to do what you need

juxt([add, flip(subtract)])(1)(7); //=> [8, 6]

Update: As pointed out in the comments, this did not capture the original requirements. I think the following approach does. It is similar to the one from @naomik, but creating a reusable function rather than simply running inline:

const callAll = curry((fns, arg) => map(fn => fn(arg), fns));

const partials = callAll([add, subtract], 10); //=> [add(10), subtract(10)]
callAll(partials, 3); //=> [10 + 3, 10 - 3] => [13, 7]

Obviously we could write this in a way that handles multiple parameters, if we desired. Using it once to create the partial functions, then again to apply the argument to them feels pretty elegant, too.

You can see this in action on the Ramda REPL.

Sign up to request clarification or add additional context in comments.

3 Comments

Interesting but juxt([add, flip(subtract)]) returns a function, not an Array
I was misunderstanding. It doesn't do to try to code on a phone! Sorry about that.
Updated with a version that seems to actually meet the requirements. :-)
2

I don't know why people insist on doing everything point-free when your code ends up looking like junk - flip this, flip that. what a brainf*ck.

pipe(flip(call), flip(map)([add, subtract]))(1)

If you have [add, subtract] and 1 and you wish to have [add(1), subtract(1)] just write the damned mapping function

map(f => f(1), [add, subtract])
// => [add(1), subtract(1)]

We can see how repeating this would give us fully applied functions

map(f => f(1), map(f => f(1), [add, subtract]))
// => [add(1)(1), subtract(1)(1)]
// => [2, 0]

If you're that fixated on writing everything point-free, write your own combinator

const $ = x => f => f (x)

R.map($(1), [R.add, R.subtract])
// => [add(1), subtract(1)]

R.map($(1), R.map($(1), [R.add, R.subtract]))
// => [add(1)(1), subtract(1)(1)]
// => [2,0]

10 Comments

map(f => f(1), [add, subtract]) is much more understandable than original solution, but to be fair that was the question: is there a better way? (yes, there is)
define "better" – better as in "your future self and coworkers will thank you for writing code they can read"-better?
(1)(1) is a lucky invocation here. R.map($(7), R.map($(1), [R.add, R.subtract])) results in [8, -6] (note the negative sign) because of the confusing nature of Ramda's partial application of infix operators.
@ScottSauyet what do you mean? R.subtract(1)(7) (1 - 7) should be -6. I'm not sure what you're pointing out.
@naomik hmm sorry if I was not clear, I meant I agree with you. Matt was asking if there was a better way than his, and I believe yours is. And for every definition of "better" I can think of :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.