A good[ish] website
Web development blog, loads of UI and JavaScript topics
Currying explained simply with few examples.
The name "currying", coined by Christopher Strachey in 1967[citation needed], is a reference to logician Haskell Curry.
This guy has a language and a programming technique named after him!
In simple terms, a curried function is a function that returns a function. Currying is generally good when you want to prepopulate a function, like shown in the examples below.
In JavaScript, curried function looks something like this:
function add(x) {
return function (y) {
return x + y
}
}
add(1)(1) // 2
But currying syntax somehow clicks together with arrow functions:
const add = x => y => x + y
add(1)(1) // 2
JavaScript is cool, it can access the first function’s params in the inner function like nothing.
If you want to call a curried function you do it like this:
const one = add(1)
const two = one(1)
console.log(two) // 2
You’re adding into it as you go.
Or:
add(1)(1)
Here’s a more realistic scenario, something that might happen in everyday work life. A curried function where the outer function can be prepopulated with a URL, and the inner function takes the required options:
// The curried function that maybe lives in a shared directoryconst getData = url => async options => {
const params = new URLSearchParams(options)
const response = await fetch(`${url}?${params.toString()}`)
return response.json()
}
// Prepopulate it with different API endpointsconst getEmployees = getData('https://hub.dummyapis.com/employee')
const getProducts = getData('https://hub.dummyapis.com/products')
;(async () => {
// Call the second half of the curried functions with needed options const employees = await getEmployees({ noofRecords: 2 })
const products = await getProducts({ noofRecords: 3, currency: 'usd' })
console.log({ employees, products })
})()
Play around with a working demo:
For example in React you get to deal with events and callback functions a lot.
In the following example that clickHandler
fn takes an event
and an id
:
const Foo = ({ id }) => {
const handleClick = (event, id) => { if (event.target.id === id) {
// something...
}
}
return (
<button id="foo" onClick={event => handleClick(event, id)}> Click
</button>
)
}
You can write it more concisely by currying the handleClick
callback, the click event will be passed to the innermost function:
const Foo = ({ id }) => {
const handleClick = id => event => { if (event.target.id === id) {
// something...
}
}
return (
<button id="foo" onClick={handleClick(id)}>
Click
</button>
)
}
That’s purely cosmetic though, I can understand if someone finds that to be a bit extra.
A random example of currying: styled-components syntax assumes currying when extending components while using the style object syntax:
const RedParagraph = styled(Paragraph)({
color: 'red'
})
You can probably sail your JavaScript career through without ever writing a curried function, but in some cases it feels very elegant.
Hope this was helpful, thanks for perusing my little blog article!
Comments would go here, but the commenting system isn’t ready yet, sorry.