So where’s that realistic example?
1
2
const people = [{ name: ‘john’ }, { name: ‘jack’ } /*, …*/ ];
const getPersonThatStartsWith = (partial) => people.filter((person) => person.name.startsWith(partial));
Here we have just your average filter on some input the user gives us (a partial name for example “joh”).
When we are thinking functionally we notice that we have the opportunity to abstract the filter function so we can reuse it later.
1
2
3
const people = [{ name: ‘john’ }, { name: ‘jack’ } /*, …*/ ];
const partialNameFilter = (partial, person) => person.name.startsWith(partial);
const getPersonThatStartsWith = (partial) => people.filter(partialNameFilter)
There is a problem here… we need to pass partial to the partialNameFilter, but we are unable to do this because we want to call the filter multiple times (once for every person in the people array). We will need to partially apply the partial to the filter (up front). This is an indication that you need to curry your function.
1
2
3
const people = [{ name: ‘john’ }, { name: ‘jack’ } /*, …*/ ];
const partialNameFilter = R.curry((partial, person) => person.name.startsWith(partial));
const getPersonThatStartsWith = (partial) => people.filter(partialNameFilter(partial))
By using the Ramda function R.curry, we are able to partially apply parameters to the function. The powerful part is that we are still able to call the function with multiple parameters at the same time. It allows us to partially apply, but does not require it!
I could therefore call the filter function like this
1
2
partialNameFilter(‘joh’, { name: ‘john’ });
partialNameFilter(‘joh’)({ name: ‘john’ });
Now this function is curried and can be used in multiple functional environments like the example above with the filter function.
Currying in functional programming
Starting out with functional programming might seem daunting at first, but if you are able to shift your mindset towards functions and passing them along as values, you will have an exciting time ahead of you!