简体   繁体   中英

Call a list of functions with the same argument in ramda

Suppose I have a list of functions that I want to call with the same argument and get a list of results. Here's my setup :

let input = 2
let fns = [add(2), add(3), add(4)]

map(x => x(input), fns)
// this is what I want. Outputs [4, 5, 6]

But I don't quite like the use of the arrow function (purely for stylistic reasons), so I wanted to rewrite it as,

map(call(__, input), fns)
// this doesn't work and produces [[Function],[Function],[Function]]

I can't figure out why x => x(input) isn't equivalent to call(__, input) . My thinking is, call(__, input) will return a function that will call its first argument with input .

Can you explain what I'm doing wrong? My hunch is that I have misunderstood the use of __ . And how do I use call or some other built-in function to elegantly write this?

I also tried,

// this also works and produces [4, 5, 6]
map(flip(call)(input), fns)

But this also does not sit well with me due to stylistic reasons. I feel like I am shoehorning something with flip , and I also don't like the consecutive function calls (...)(...) .

You are looking for R.juxt :

juxt applies a list of functions to a list of values.

 const { add, juxt } = R const input = 2 const fns = [add(2), add(3), add(4)] const addTo = juxt(fns) const result = addTo(input) console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

Ori Drori showed that juxt will do what you want.

As to why call doesn't work... honestly, it's perhaps the worst-designed function in all of Ramda. (I'm one of the founders of Ramda and I think I wrote it, so I'm not insulting anyone but myself.)

There is very, very little need for it. Why would you write call(fn, 1, 2) when you could just write fn(1, 2) . Currying doesn't work properly since it's variadic, which is itself a problem. Even the example is pretty unclear, mostly because it's hard to find any meaningful example.

I would just skip using it, personally.

But I don't quite like the use of the arrow function (purely for stylistic reasons), so I wanted to rewrite it as,

From the comments, I'm assuming that you don't mean arrow functions as opposed to function declarations or function expressions, but rather that you'd prefer to write this point-free. A suggestion: use a point-free style where it makes your code more readable, but skip it when it doesn't; don't make a fetish out of it.

Here juxt([add(2), add(3), add(4)]) seems fine, so long as juxt (short for juxtapose ) makes sense to you. But often enough, pushing for point-free seems to cause more harm than good.

I also tried,

 // this also works and produces [4, 5, 6] map(flip(call)(input), fns)

But this also does not sit well with me due to stylistic reasons. I feel like I am shoehorning something with flip ,

I tend to agree. flip is not a wonderful solution to nearly any problem. But I usually like the placeholder even less. There's just no satisfying me!

and I also don't like the consecutive function calls (...)(...) .

Here I disagree. I've switched my own code to an almost-universally fully-curried style. If that involves multiple consecutive function calls and the dreaded parentheses butt, so be it. I simply find it easier to work with and to reason about.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM