What is currying ?
Currying is an advanced technique of working with functions. It is a transformation of functions that translates a function from callable as f(x, y, x) into callable as f(x)(y)(z).
Example :
//Normal function
function add(x, y) {
return x + y
}
add(1, 2) //3
//Curried function
function add(x) {
return function (y) {
return x + y
}
}
add(1)(2) //3
Why currying
With currying we can break function in to pieces and can reuse those pieces.
“Breaking function in to pieces and reusing” does it sounds crazy ? 🤔
Here is an basic example :
function add(x) {
return function (y) {
return x + y
}
}
const addTen = add(10)
addTen(5) //15
addTen(90) //100
Now lets see simple real world example
function logger(type) {
function createLogRequest(endPoint) {
return function (data) {
return fetch(`<DOMAIN>/${endPoint}`, {
method: "POST",
body: data,
})
}
}
const sendLogs = createLogRequest(type)
const showLogs = console[type] || console.log
const transformData = data => `${new Date()} : ${JSON.stringify(data)}`
return function (logData) {
const data = transformData(logData)
sendLogs(data)
showLogs(data)
}
}
const infoLog = logger("info")
const errorLog = logger("error")
const warningLog = logger("warning")
infoLog("Some Info....") //Calls /info api and shows info with date
errorLog("Some Error....") //Calls /error api and shows error with date
warningLog("Some Warning....") //Calls /waningr api and shows warning with date
Function memorisation will be easy
const add = a => {
const memo = {}
return b => {
return c => {
const storedResult = memo[`${a}+${b}+${c}`]
if (storedResult) return storedResult
console.log("evaluating")
const result = a + b + c
memo[`${a}+${b}+${c}`] = result
return result
}
}
}
const addOne = add(1)
const addThree = addOne(2)
addThree(5)
addThree(5)
addThree(6)
Can we convert normal function to curry function 🤔 ?
Yes of-course with the following code we can use function in both curry and normal way.
Here is an example for that
function curry(func) {
function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args)
} else {
return function (...args2) {
return curried.call(this, ...args, ...args2)
}
}
}
return curried.bind(this)
}
const add = (a, b, c) => a + b + c
const curriedAdd = curry(add)
//curried
curriedAdd(1)(2)(3) //6
//normal
curriedAdd(1, 2, 3) //6
//curried + normal
curriedAdd(1, 2)(3) //6
Hope you learned something new and interesting 🤨
Thank you!!!