Scala Higher-order Function Flashcards

1
Q

Higher-order function (HOF)

Definition

A

Higher order functions take other functions as parameters or return a function as a result. This is possible because functions are first-class values in Scala.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

map()

Write example of this HOF

A
val salaries = Seq(20_000, 70_000, 40_000)
val doubleSalary = (x: Int) => x * 2
val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000)

doubleSalary is a function which takes a single Int, x, and returns x * 2. In general, the tuple on the left of the arrow => is a parameter list and the value of the expression on the right is what gets returned. On line 3, the function doubleSalary gets applied to each element in the list of salaries.

Also can be written with anonymous function:
~~~
val salaries = Seq(20_000, 70_000, 40_000)
val newSalaries = salaries.map(x => x * 2)
~~~

or:

val salaries = Seq(20_000, 70_000, 40_000)
val newSalaries = salaries.map(_ * 2)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Coerce methods into functions

Write example

A
case class WeeklyWeatherForecast(temperatures: Seq[Double]) {

  private def convertCtoF(temp: Double) = temp * 1.8 + 32

  def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF) // <-- passing the method convertCtoF
}

Here the method convertCtoF is passed to the higher order function map. This is possible because the compiler coerces convertCtoF to the function x => convertCtoF(x) (note: x will be a generated name which is guaranteed to be unique within its scope).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Functions that accept functions

Write example

A
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)
}

Notice how each of the three methods vary only by the multiplication factor. To simplify, you can extract the repeated code into a higher-order function like so:

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly