Scala - Currying Functions



This chapter takes you through the concept of currying functions in Scala programming. Currying is a technique that transforms a function with multiple arguments into a sequence of functions that each with a single argument.

Currying Functions

You can decompose a function that takes multiple parameters into a series of functions that each take a single parameter. It is used to create more modular and reusable code.

Currying is the process of transforming a function that takes multiple arguments into a chain of functions each taking a single argument.

Syntax

The syntax of a curried function in Scala is -

 def functionName(arg1: Type1)(arg2: Type2)(arg3: Type3): ReturnType = { // function body } 

Example

The following example shows defining and using a curried function in Scala programming -

 object Demo { def add(a: Int)(b: Int): Int = { a + b } def main(args: Array[String]): Unit = { println(add(3)(4)) // Output: 7 val addThree = add(3) _ println(addThree(4)) // Output: 7 } } 

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

 > scalac Demo.scala > scala Demo 

Output

 7 7 

In the example, the add function is curried. So it has to be called with one argument at a time.

Advantages of Currying Functions

There are various advantages of Currying functions. You can fix a few arguments of a function and produce a new function with less number of arguments. It is easier to build complex functions from simpler ones. You can also work with higher-order functions. So it enhances code modularity and reusability.

Partial Application with Currying

You can also use currying functions through partial application. You partially apply a function by fixing some of its arguments and returning a new function.

Syntax

The syntax for partially applying a curried function is -

 def functionName(param1: Type1)(param2: Type2): ReturnType = { // function body } val partiallyAppliedFunction = functionName(fixedParam1) _ 

Example

Consider the example of partial application with curried functions in Scala programming -

 object Demo { def multiply(a: Int)(b: Int): Int = { a * b } def main(args: Array[String]): Unit = { val multiplyByTwo = multiply(2) _ println(multiplyByTwo(5)) println(multiplyByTwo(10)) } } 

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

 > scalac Demo.scala > scala Demo 

Output

 10 20 

In the example, the multiply function is curried. It is partially applied to create a new function multiplyByTwo.

Currying and Function Composition

You can compose functions to pass partially applied functions as arguments to other functions.

Syntax

The syntax for composing functions with currying is -

 def function1(param1: Type1)(param2: Type2): ReturnType1 = { // function1 body } def function2(param: Type3): ReturnType2 = { // function2 body } val composedFunction = function2 _ compose function1(fixedParam1) 

Example

Consider the example of function composition with curried functions in Scala programming -

 object Demo { def add(a: Int)(b: Int): Int = a + b def double(x: Int): Int = x * 2 def main(args: Array[String]): Unit = { val addThree = add(3) _ val addThreeAndDouble = double _ compose addThree println(addThreeAndDouble(4)) } } 

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

 > scalac Demo.scala > scala Demo 

Output

 14 

In the example, the add function is curried. It is composed with the double function to create a new function addThreeAndDouble.

Currying and Higher-Order Functions

You can use Currying combined with higher-order functions. So you can create highly modular and reusable code.

Syntax

The syntax for using curried functions with higher-order functions is -

 def higherOrderFunction(f: Type1 => Type2): ReturnType = { // function body calling f } def curriedFunction(param1: Type1)(param2: Type2): ReturnType = { // function body } 

Example

Consider the example of using curried functions with higher-order functions in Scala programming -

 object Demo { def applyFunction(f: Int => Int, x: Int): Int = { f(x) } def add(a: Int)(b: Int): Int = a + b def main(args: Array[String]): Unit = { val addFive = add(5) _ println(applyFunction(addFive, 10)) } } 

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

 > scalac Demo.scala > scala Demo 

Output

 15 

In the example, the add function is curried. It passed as an argument to the higher-order function applyFunction.

Currying and Recursion

You can apply Currying in recursive functions to create elegant and concise solutions to complex problems.

Syntax

The syntax for recursive curried functions is -

 def recursiveFunction(param1: Type1)(param2: Type2): ReturnType = { // base case if (condition) baseResult else { // recursive case recursiveFunction(newParam1)(newParam2) } } 

Example

Consider the example of recursive curried functions in Scala programming -

 object Demo { def gcd(a: Int)(b: Int): Int = { if (b == 0) a else gcd(b)(a % b) } def main(args: Array[String]): Unit = { println(gcd(54)(24)) } } 

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

 > scalac Demo.scala > scala Demo 

Output

 6 

In the example, the gcd function is a recursive curried function. It computes the greatest common divisor of two numbers.

Currying Recursion Summary

  • Currying transforms a function with multiple arguments into a sequence of functions that each with a single argument.
  • You can use Currying in partial application, function composition, and with higher-order functions. So, it is easier to create new functions by fixing some arguments of existing functions.
  • The syntax for declaring curried functions can be different but the core concept remains the same.
  • It enhances code modularity and reusability because functions are broken down into simpler and more manageable parts.
  • It can be used in recursion and combined with other functions to solve complex problems elegantly.
Advertisements