
- Scala - Home
- Scala - Overview
- Scala - Features
- Scala - Environment Setup
- Scala - Build Tool (SBT)
- Scala - REPL
- Scala - Dot & Dotty
- Scala - Basic Syntax
- Scala - Hello World Program
- Scala - Identifiers
- Scala - Keywords
- Scala - Comments
- Scala - Code Blocks
- Scala - Semicolon
- Scala - Constructs
- Scala - Expressions
- Scala - Input and Output
- Scala - Optional Braces
- Scala - Underscore (_)
- Data Types and Variables
- Scala - Data Types
- Scala - Type Bounds
- Scala - Context Bound
- Scala - Variances
- Scala - Type Hierarchy
- Scala - Variables
- Scala - Variable Scopes
- Scala - Literals
- Scala - Numeric Types
- Scala - Boolean Types
- Scala - Char Type
- Scala - Unit Types
- Scala - Strings
- Scala - Arrays
- Scala - Null Type
- Scala - Nothing
- Scala - Any Type
- Scala - AnyRef Type
- Scala - Unified Types
- Scala - Dates and Times
- Scala - Ranges
- Scala - Multidimensional Arrays
- Scala - WrappedArray
- Scala - StringBuilder
- Scala - String Interpolation
- Scala - StringContext
- Scala - Type Casting
- Scala var vs val
- Scala Operators
- Scala - Operators
- Scala - Rules for Operators
- Scala - Arithmetic Operators
- Scala - Relational Operators
- Scala - Logical Operators
- Scala - Bitwise Operators
- Scala - Assignment Operators
- Scala - Operators Precedence
- Scala - Symbolic Operators
- Scala - Range Operator
- Scala - String Concatenation Operator
- Scala Conditional Statements
- Scala - IF ELSE
- Scala - IF-ELSE-IF-ELSE Statement
- Scala - Nested IF-ELSE Statement
- Scala Loop Statements
- Scala - Loop Statements
- Scala - while Loop
- Scala - do-while Loop
- Scala - Nested Loops
- Scala - for Loop
- Scala - break Statement
- Scala - yield Keyword
- Scala Classes & Objects
- Scala - Classes & Objects
- Scala - Constructors
- Scala - Auxiliary Constructor
- Scala - Primary Constructor
- Scala - This Keyword
- Scala - Nested Classes
- Scala - Getters and Setters
- Scala - Object Private Fields
- Scala - Singleton Object
- Scala - Companion Objects
- Scala - Creating Executable Programs
- Scala - Stateful Object
- Scala - Enumerations
- Scala - Polymorphism
- Scala - Access Modifiers
- Scala - Apply Method
- Scala - Update Methods
- Scala - UnapplySeq Method
- Scala - Inheritance
- Scala - Extending a Class
- Scala - Method Overloading
- Scala - Method Overriding
- Scala - Generic Classes
- Scala - Generic Functions
- Scala - Superclass Construction
- Scala Methods & Functions
- Scala - Functions
- Scala - Main Methods
- Scala - Functions Call-by-Name
- Scala - Functions with Named Arguments
- Scala - Function with Variable Arguments
- Scala - Recursion Functions
- Scala - Default Parameter Values
- Scala - Functions without Parameters
- Scala - Implicit Parameters
- Scala - Higher-Order Functions
- Scala - Nested Functions
- Scala - Extension Methods
- Scala - Anonymous Functions
- Partially Applied Functions
- Scala - Lazy Val
- Scala - Pure Function
- Scala - Currying Functions
- Scala - Control Abstractions
- Scala - Corecursion
- Scala - Unfold
- Scala - Tail Recursion
- Scala - Infinite Sequences
- Scala - Dynamic Invocation
- Scala - Lambda Expressions
- Scala Collections
- Scala - Collections
- Mutable and Immutable Collections
- Scala - Lists
- Scala - Sets
- Scala - Maps
- Scala - TreeMap
- Scala - SortedMap
- Scala - Tuples
- Scala - Iterators
- Scala - Options
- Scala - Infinite Streams
- Scala - Parallel Collections
- Scala - Algebraic Data Types
- Scala Pattern Matching
- Scala - Pattern Matching
- Scala - Type Patterns
- Scala - Exception Handling
- Scala - Extractors
- Scala - Regular Expressions
- Scala Files I/O
- Scala - Files I/O
- Scala Advanced Concepts
- Scala - Closures
- Scala - Futures
- Scala - Promises
- Scala - Traits
- Scala - Trait Mixins
- Scala - Layered Traits
- Scala - Trait Linearization
- Scala - Sealed Traits
- Scala - Transparent Traits
- Scala - Literal Type Arithmetic
- Scala - Inline keyword
- Scala - Def, Var & Val
- Scala - Dropped Features
- Scala - BDD Testing
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.