Things about to know in Higher-Order Functions

Reading Time: 3 minutes

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:

  1. addition(squareSum, 1, 2) will call squareSum(1,2).
  2. addition(cubeSum, 1, 2) will call cubeSum(1,2).
  3. 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/

Written by 

Ujjawal singh is a Software intern in Knoldus Inc. I have completed my B.tech in Computer Science stream from IMS Engineering College, Ghaziabad.