Currying in JavaScript — What | Why | How
This article will cover below topics.
- What is Currying?
- How to implement Currying?
- What is the use of Currying?
- What is partial or partially applied function?
- Live example of Currying & partially applied function.
What is Currying?
Currying is a technique that translates the function with multiple arguments (arity) to the sequence of multiple functions with single argument (arity) each.
e.g. Currying will translate the function foo(a, b, c) to curriedFoo(a)(b)(c).
How to implement Currying?
/**
* This function curries the function passed to it as argument.
*/
function currying(functionToBeCurried) {
return function curriedFunction(...args) {
if (args.length >= functionToBeCurried.length) {
return functionToBeCurried.apply(this, args)
} else {
return function (...args2) {
return curriedFunction.apply(this, args.concat(args2))
}
}
}
}
Code Flow:
If the number of arguments provided are same or more than the original function parameters then invoke the original function. Otherwise return another function which will apply “curriedFunction” recursively till all the remaining arguments has been provided.
Note: The Lodash provides the Curry function which can be used in production.
Curried version of a function:
Let’s create a curried version of a function “printBill()” with the help of above “currying()” function.
const prices = {
"Product 1": 10,
"Product 2": 20,
"Product 3": 30,
}
/**
* This function will get curried.
*/
function printBill(date, productName, quantity) {
let headerString = "Date Product Total"
let message = `${date.toDateString()} ${productName} ${quantity * prices[productName]}`
console.log(headerString)
console.log(message)
console.log()
console.log()
}
// Curried version of the printBill.
let curriedPrintBill = currying(printBill)
Now we can call the original function and curried function as below.
const today = new Date()
console.log("Result of calling original function...")
printBill(today, "Product 1", 10) // Original function.
console.log("Result of calling curried function with original arguments...")
curriedPrintBill(today, "Product 1", 10) // Curried function with original arguments.
console.log("Result of calling curried function with single argument...")
curriedPrintBill(today)("Product 1")(10) // Curried function with single argument.
console.log("Result of calling curried function with multiple arguments...")
curriedPrintBill(today)("Product 1", 10) // Curried function with multi-argument variant.
Why Currying: What is the use of it?
Currying can be used to create “partially applied function” or “partial”. Partially applied function is curried version of original function with few arguments fixed. Sometimes it is convenient to use them as shown below.
e.g. All the below partial versions will produce the same output.
// Create 'partially applied function' with today's date.
// The first argument of 'printTodaysBill()' is fixed to today's date.
let printTodaysBill = curriedPrintBill(today)
console.log("Result of calling 'partially applied function' which has first argument 'Date' as fixed.")
printTodaysBill("Product 1", 10)
// Another 'partially applied function' with today's date and Product 1 as fixed arguments.
let printTodaysBillForProduct1 = curriedPrintBill(today)("Product 1")
console.log(
"Result of calling 'partially applied function' with today's date and 'Product 1' as fixed arguments.",
)
printTodaysBillForProduct1(10)
Live Example
Check my JavaScript Currying JSFiddle for live demo of above code snippets.
Top comments (0)