Scala Higher-Order Functions

A higher-order function either accepts another function as a parameter, returns a function as its result, or both. Functions that treat other functions as data are a cornerstone of functional programming. Scala's standard library is built around higher-order functions — map, filter, and foldLeft are all higher-order functions you will use every day.

Functions as Parameters

def applyTwice(f: Int => Int, x: Int): Int = f(f(x))

def double(n: Int): Int = n * 2
def addTen(n: Int): Int = n + 10

println(applyTwice(double, 3))    // double(double(3)) = double(6) = 12
println(applyTwice(addTen, 5))    // addTen(addTen(5)) = addTen(15) = 25

applyTwice(double, 3)
     │
     ├── first call:  f(3)    = double(3)   = 6
     └── second call: f(6)    = double(6)   = 12

The Function Type Syntax


Int => String         // function from Int to String
(Int, Int) => Boolean // function from two Ints to Boolean
String => Unit        // function that takes String, returns nothing
() => Int             // function with no input, returns Int

Functions That Return Functions

def multiplier(factor: Int): Int => Int =
  (n: Int) => n * factor

val triple = multiplier(3)
val quadruple = multiplier(4)

println(triple(5))    // 15
println(quadruple(7)) // 28
println(multiplier(10)(6))  // 60

Using map, filter, foldLeft

val prices = List(100.0, 250.0, 80.0, 500.0, 30.0)

// map: transform each element
val withTax = prices.map(p => p * 1.18)
println(withTax.map(x => f"₹$x%.0f"))
// List(₹118, ₹295, ₹94, ₹590, ₹35)

// filter: keep matching elements
val expensive = prices.filter(_ > 100)
println(expensive)   // List(250.0, 500.0)

// foldLeft: accumulate a result
val total = prices.foldLeft(0.0)(_ + _)
println(f"Total: ₹$total%.2f")   // Total: ₹960.00

Composing Functions

val add5: Int => Int    = _ + 5
val times3: Int => Int  = _ * 3

// andThen: apply f, then g
val add5ThenTimes3 = add5 andThen times3
println(add5ThenTimes3(4))   // (4+5)*3 = 27

// compose: apply g, then f (reverse order)
val times3ThenAdd5 = add5 compose times3
println(times3ThenAdd5(4))   // (4*3)+5 = 17

Practical: Event Pipeline

case class Event(name: String, value: Double, tag: String)

val events = List(
  Event("sale", 500.0, "retail"),
  Event("refund", -100.0, "retail"),
  Event("sale", 2000.0, "wholesale"),
  Event("fee", -50.0, "retail")
)

def processEvents(
  events: List[Event],
  filter: Event => Boolean,
  transform: Event => Double,
  aggregate: (Double, Double) => Double
): Double =
  events.filter(filter).map(transform).foldLeft(0.0)(aggregate)

val retailTotal = processEvents(
  events,
  filter = _.tag == "retail",
  transform = _.value,
  aggregate = _ + _
)
println(f"Retail total: ₹$retailTotal%.2f")   // Retail total: ₹350.00

Leave a Comment

Your email address will not be published. Required fields are marked *