Can I make this feature even more limited?

I am trying to transition to functional programming in my javascript applications. I am currently using the ramda library as my base library for this.

My desire:

  • Create a function findWithId(id, list)

    that returns an item in a list with a property _id

    that matches the ID of the input.
  • Keep it as short as possible, building on the existing code as much as possible.

Achieved so far:

My base R.find

which has this defenition find :: (a -> Boolean) -> [a] -> a | undefined

I tried several different solutions shown below:

//Using ramdajs (ramdajs.com)
var hasId = R.curry(function(id, item) {
  return item._id === id
});

//This doesn't work
var findWithId_v1 = R.find(hasId);

//This works but can I make it as short as v1?
var findWithId_v2 = function(id, list) {
  return R.find(hasId(id), list);
}

      

Question

Can I make it findWithId_v2

shorter findWithId_v1

with standard functional programming tools like compose, curry, etc.

Plunker demo

http://plnkr.co/edit/xAYx15yk6lBzutdAL9HC?p=preview

+3


source to share


2 answers


Ramda has a function to help with this called useWith

. If you can think of a better name I would love that. I asked what up .

You can use like this:

var findById = R.useWith(R.find, hasId, R.identity);

var find5 = findById(5);
find5([{id:3}, {id:5}]); //=> {id:5} 
findById(5, [{id:3}, {id:5}]); //=> {id:5} 

      



You don't need to supply R.identity

above. This will work as well, although I prefer to be explicit:

var findById = R.useWith(R.find, hasId);

      

useWith "takes a function fn

and any number of transformer functions and returns a new function. When a new function is called, it calls the function fn

with parameters consisting of the result of calling each supplied handler on the sequential arguments of the new function."

+3


source


You are looking for a function compose

:

compose :: (a -> b) -> (b -> c) -> (a -> c)
hasId :: p -> (i -> Boolean)
find :: (i -> Boolean) -> ([i] -> i | undefined)
compose :: (p -> (i -> Boolean))
           -> ((i -> Boolean) -> ([i] -> i | undefined))
           -> (p -> ([i] -> i | undefined))
compose find hasId :: p -> ([i] -> i | undefined)

      

So you would do



var findWithId = R.compose(R.find, hasId)

      

Oh, and note that you don't need a function expression for hasId

:

var hasId = R.propEq('_id');

      

0


source







All Articles