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
source to share
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."
source to share
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');
source to share