Lopatin - 1 year ago 76

Javascript Question

My goal is to create a custom map function that first needs to filter the list to remain, for example, only even items before invoking the supplied function on every item. I do need the function to be curried and for the first parameter to be the function, not the list. I believe the signature would look like this:

`(a -> b) -> [a] -> [b]`

There are of course many ways to do this. Here is what my first attempt looked like.

`var isEven = x => x % 2 === 0;`

var filterEvensMap = R.curry((fn, items) => R.map(fn, R.filter(isEven, items)));

filterEvensMap(R.negate, [1,2,3,4]); // [-2, -4]

However, since the above uses an anonymous function with the

`fn`

`items`

Below I included another way to do it. It seems to be more in the spirit of Ramda but I'm not sure if I'm over complicating things.

`var filterEvensMap = R.compose(`

R.flip,

R.uncurryN(2)

)(R.compose(

R.flip(R.map),

R.filter(isEven)

));

Am I overcomplicating with the multiple composes and uncurryN? Is there a more idiomatic way to achieve this? In your experience, does it matter?

Thanks in advance.

Answer Source

If you find Haskell signatures useful you may find this point-free generator (source) useful too. If you want to simplify an expression you can enter the Haskell equivalent to your JS code:

```
filterEvensMap = \fn items -> map fn (filter isEven items)
```

And it will give you a point-free equivalent:

```
filterEvensMap = (. filter isEven) . map
```

Then translate back to JS using Ramda:

```
var filterEvensMap = R.curry(R.compose(R.compose(R.filter(isEven)), R.map))
```

In your experience, does it matter?

I would go with the most readable expression, which in this case is probably the original expression. Point-free is fun and can add clarity in some places, but it can reduce readability considerably too, or at least level of understanding.