Step 1 of 5 · Reading · ~1 min
Learn
Functions
Functions that take or return other functions are higher-order. Scala's standard library leans heavily on them.
def apply3Times(f: Int => Int, x: Int): Int = f(f(f(x)))
val doubled = apply3Times(_ * 2, 1) // 8
Underscore syntax _ * 2 is shorthand for (x: Int) => x * 2 — each _ becomes a parameter in order.
Classic higher-order on collections:
val nums = List(1, 2, 3, 4, 5)
nums.map(_ * 2) // List(2, 4, 6, 8, 10)
nums.filter(_ % 2 == 0) // List(2, 4)
nums.reduce(_ + _) // 15
nums.fold(100)(_ + _) // 115
nums.forall(_ > 0) // true
nums.exists(_ > 4) // true
This is where Scala feels different from Java — write composable transformations instead of explicit loops.
The underscore trap
An underscore stands for a parameter only when you have not already declared one.
Writing _ => declares a parameter and then throws its name away, so a later _
in the same literal has nothing left to stand for:
nums.filter(_ % 2 == 0) // fine: the _ IS the parameter
nums.filter(x => x % 2 == 0) // the same function, spelled out
nums.filter(_ => _ % 2 == 0) // error: missing parameter type
The compiler reports missing parameter type for expanded function, which reads as a
type problem but is really this shape problem. Pick one form and stay in it: a bare
underscore for the whole expression, or a named parameter with =>. Never both.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…