"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > JavaScript Currying

JavaScript Currying

Published on 2024-08-07
Browse:929

JavaScript Currying

Currying is a powerful concept in functional programming that transforms a function with multiple arguments into a sequence of functions, each taking a single argument. This technique allows for more modular and reusable code. In JavaScript, currying can be implemented in various ways. This blog will explore currying, provide examples, and discuss different methods to achieve n argument currying.

What is Currying?

Currying is the process of converting a function that takes multiple arguments into a series of functions that each take a single argument. For example, a function f(a, b, c) can be transformed into f(a)(b)(c).

Why Use Currying?

  • Partial Application: Currying allows you to fix some arguments of a function and create a new function.
  • Higher-Order Functions: It facilitates the use of higher-order functions, which take other functions as arguments or return them.
  • Code Reusability: Curried functions are more reusable and composable.
  • Functional Composition: Currying enables better functional composition, where complex functions are built by combining simpler functions, leading to cleaner and more maintainable code.

Simple Currying Example

Let's start with a basic example to understand how currying works.

Uncurried Function

Here's a simple function that adds three numbers:

function add(a, b, c) {
  return a   b   c;
}

console.log(add(1, 2, 3)); // Output: 6

Explanation: This function add takes three arguments a, b, and c, and returns their sum. When we call add(1, 2, 3), it returns 6.


Curried Function

Now, let's convert this function into a curried version:

function curryAdd(a) {
  return function(b) {
    return function(c) {
      return a   b   c;
    };
  };
}

console.log(curryAdd(1)(2)(3)); // Output: 6

Explanation: The curryAdd function takes an argument a and returns a function that takes an argument b, which in turn returns a function that takes an argument c. The final function returns the sum of a, b, and c. When we call curryAdd(1)(2)(3), it sequentially passes the arguments 1, 2, and 3 through the nested functions, resulting in 6.

Currying with Arrow Functions

JavaScript's arrow functions provide a concise way to create curried functions.

const curryAddArrow = a => b => c => a   b   c;

console.log(curryAddArrow(1)(2)(3)); // Output: 6

Explanation: The curryAddArrow function is an arrow function that takes an argument a and returns another arrow function that takes b, which returns yet another arrow function that takes c. The final arrow function returns the sum of a, b, and c. When we call curryAddArrow(1)(2)(3), it sequentially passes the arguments 1, 2, and 3 through the nested arrow functions, resulting in 6.


Use Case

1.Configuration Functions

A common use case for currying is configuration functions. For instance, imagine you are creating a logging utility where you want to configure the logging level and the message format separately.

function logger(level) {
  return function (message) {
    console.log(`[${level}] ${message}`);
  };
}

const infoLogger = logger('INFO');
const errorLogger = logger('ERROR');

infoLogger('This is an info message');
errorLogger('This is an error message');

2. String Formatter

Let's consider a practical example where currying can be used to create a string formatter. This formatter will allow you to configure the prefix and suffix separately.

function formatter(prefix) {
  return function (suffix) {
    return function (str) {
      return `${prefix}${str}${suffix}`;
    };
  };
}

const htmlFormatter = formatter('')('');
console.log(htmlFormatter('Hello')); // Hello

const parensFormatter = formatter('(')(')');
console.log(parensFormatter('123')); // (123)

Currying in Modern JavaScript Libraries

Currying is commonly used in modern JavaScript libraries like Lodash and Ramda. For example, in Lodash, you can use the _.curry method to create curried functions easily.

const _ = require('lodash');

function multiply(a, b, c) {
  return a * b * c;
}

const curriedMultiply = _.curry(multiply);

console.log(curriedMultiply(2)(3)(4)); // 24
console.log(curriedMultiply(2, 3)(4)); // 24

Currying with N Arguments

Let go through below example of currying with a recursive function that adds n arguments. We'll use currying to create a function that can accept any number of arguments, one at a time, and add them together.

function curryAddition(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    } else {
      return function(...nextArgs) {
        return curried(...args, ...nextArgs);
      };
    }
  };
}

// This function sums an array of numbers
function add(...nums) {
  return nums.reduce((acc, num) => acc   num, 0);
}

// Creating a curried version of the addition function
const curriedAdd = curryAddition(add);

// Function to handle n arguments
function curriedAddN(...initialArgs) {
  function adder(...args) {
    if (args.length === 0) {
      return curriedAdd(...initialArgs);
    }
    initialArgs.push(...args);
    return adder;
  }
  return adder;
}

// Examples
const addFiveNumbers = curriedAddN();
console.log(addFiveNumbers(1)(2)(3)(4)(5)()); // 15

const addThreeNumbers = curriedAddN(1)(2)(3);
console.log(addThreeNumbers()); // 6

const addNumbersInSteps = curriedAddN(1, 2)(3)(4, 5);
console.log(addNumbersInSteps()); // 15

Conclusion

Currying is a powerful technique in functional programming that enhances modularity and reusability of code. By transforming functions into chains of single-argument functions, currying allows for partial application and flexible function composition. Whether for configuration, string formatting, or complex computations, currying can make your code more expressive and adaptable.

Release Statement This article is reproduced at: https://dev.to/rahulvijayvergiya/javascript-currying-op2?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3