Reputation: 882
Take the following example imperative JavaScript example:
getAnimalList = (hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
if(hasCat){
baseAnimals.cat = animLib.cat();
}
return baseAnimals
}
I am trying to write this code in a functional style with Ramda, but the only way I can do so is by having the functions reach outside of scope:
getAnimalList = (hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
return when(always(hasCat), merge({hasCat: animLib.cat()}))(baseAnimals)
}
Leaving aside how animLib
is outside of scope, the way I would fix has hasCat
from being pass from the outside(if this is a problem at all) is the following:
getAnimalList = (hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
const mergeCat = when(compose(equals(true), prop('hasCat')),
compose(merge({hasCat: animLib.cat()}), prop('baseAnimals')));
return mergeCat({hasCat: hasCat, baseAnimals: baseAnimals});
}
But this makes the code incredibly verbose. Is there a better way to do this? Or is the verbosity just the cost of keeping the code more pure.
Upvotes: 0
Views: 320
Reputation: 50787
It seems to me that this would do fine:
getAnimalList = (animLib, hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
return hasCat ? merge({hasCat: animLib.cat()}, baseAnimals) : baseAnimals;
}
Because Ramda's when
and ifElse
are based around predicate functions rather than boolean values, using them seems to be overkill here.
Obviously if you want a version that has animLib
in scope, you can curry this function, either with something like Ramda's curry
or just by changing to
getAnimalList = (animLib) => (hasCat) => { /* ... */ }
Then you can create newAnimalList = getAnimalList(myAnimLib)
.
Upvotes: 1