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
