Introduction:
Functions are first-class citizens in Scala: we can use them as parameters or return them as the result of some computation. Higher-order functions are functions that accept other functions as parameters, therefore return functions, or both as a value. Their use allows us to create powerful abstractions that reduce duplication and increase the reusability of your code.

Functions that accept functions:
The reason to use higher-order functions is to reduce the redundancy of code. In other words, If you wanted some methods that could raise someone’s salaries by various factors. Without creating a higher-order function, it might look something like this:
object SalaryRaiser {
def smallPromotion(salaries: List[Double]): List[Double] =
salaries.map(salary => salary * 1.1)
def greatPromotion(salaries: List[Double]): List[Double] =
salaries.map(salary => salary * math.log(salary))
def hugePromotion(salaries: List[Double]): List[Double] =
salaries.map(salary => salary * salary)
}
Here, each of the three methods varies only by the multiplication factor. So, we extract the repeated code into a higher-order function like shown here:
object SalaryRaiser {
private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] =
salaries.map(promotionFunction)
def smallPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * 1.1)
def greatPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * math.log(salary))
def hugePromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * salary)
}
The new method, promotion
, takes the salaries plus a function of type Double => Double
(i.e. a function that takes a Double and returns a Double) and returns the product.
Functions that return functions:
There are certain cases where we want to generate a function. Here’s an example.
def addition(f: (Int, Int) => Int,a: Int, b:Int): Int = f(a,b)
In addition snippet below takes a higher-order function as an input, which, in turn, takes two integers as an input and returns an integer.
val squareSum = (x: Int, y: Int) => (x*x + y*y)
val cubeSum = (x: Int, y: Int) => (x*x*x + y*y*y)
val intSum = (x: Int, y: Int) => (x + y)
val squaredSum = addition(squareSum, 1, 2)
val cubedSum = addition(cubeSum, 1, 2)
val normalSum = addition(intSum, 1, 2)
See that:
- addition(squareSum, 1, 2) will call squareSum(1,2).
- addition(cubeSum, 1, 2) will call cubeSum(1,2).
- addition(intSum, 1, 2) will call intSum(1,2).
Commonly used Higher-order functions in Scala:
Map
A map is a function that can transform one collection into another collection by applying a function to each element. Let’s implement the same.
Example:
scala> val words = List("my","name","is","rahul")
words: List[String] = List(my, name, is, rahul)
scala> words.map(_.length)
res0: List[Int] = List(2, 4, 2, 5)
Flatmap
A FlatMap is a function that removes the inner grouping of an item and generates a sequence in the collection. In other words, it is defined as a blend of map method followed by the flatten method.
Example:
scala> val words = List("my","name","is","rahul")
words: List[String] = List(my, name, is, rahul)
scala> words.flatMap(_.toList)
res2: List[Char] = List(m, y, n, a, m, e, i, s, r, a, h, u, l)
Filter
A Filter method selects those elements of a collection that pass a test the user supplies. For instance, that test is supplied using a function
Example:
scala> val someNumbers = List(-11, -10, -5, 0, 5, 10)
someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)
scala> someNumbers.filter((x: Int) => x>0 )
res3: List[Int] = List(5, 10)
Conclusion:
In this blog, we have learned about the higher-order function like map, flatmap, filter in Scala, and how to make use of it!
References:
https://docs.scala-lang.org/tour/higher-order-functions.html
https://www.geeksforgeeks.org/higher-order-functions-in-scala/