HonoredMule
HonoredMule

Reputation: 769

How to use Ramda's useWith

I am implementing a function which performs the following detail-abstracted search, for which this example implementation works:

// findRecord :: id → [{id: number}] → {id: number}|null
const findRecord = R.curry((id, list) => R.find(R.propEq('id', id), list));
findRecord(1, [{id: 1}]); // {id: 1}

I am trying instead to implement the method using useWith ( https://ramdajs.com/docs/#useWith ):

// findRecord :: id → [{id: number}] → {id: number}|null
const findRecord = R.useWith(R.find, [R.propEq('id'), R.identity]);
findRecord(1, [{id: 1}]); // Error('r[u] is not a function')

Where am I going wrong? Am I misunderstanding useWith's signature/usage, and if so would another Ramda function serve me better here? ("Better" meaning similarly terse even if written in ES5, yet still reasonably accessible to fellow programmers.)

REPL

Upvotes: 1

Views: 405

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370639

You're doing it right. The only problem is that the version of the REPL you're using:

https://ramdajs.com/repl/?v=0.17.1#?const%20data...

is 0.17.1, while the documentation you're reading is for the most recent version, 0.25.0.

You can see the problem if you look at the source code, In 0.17.1, useWith starts with:

module.exports = curry(function useWith(fn /*, transformers */) {
  var transformers = _slice(arguments, 1);
  var tlen = transformers.length;
  // ...

That is, the transformer functions are expected to be plain arguments following the initial fn, eg R.useWith(R.find, R.propEq('id'), R.identity);. If you use useWith like that, then in your 0.17.1 REPL version, it'll work as expected:

const findProject1 = R.useWith(R.find, R.propEq('id'), R.identity);
findProject1(1, [{id:1}, {id: 2}]);

Output:

{"id": 1}

But in 0.18.0 and later, the transformers are expected to be passed as an array, in the second argument, rather than as a list of parameters. See the source:

module.exports = _curry2(function useWith(fn, transformers) {
  return curry(_arity(transformers.length, function() {
  // ...

The change looks to stem from this issue, among others.

So, either upgrade to a more recent version of Ramda, or use useWith by passing in functions as individual parameters, rather than an array. Your code works as expected in 0.18.0+.

Upvotes: 1

Related Questions