Scala Tutorial
Basics
Control Statements
OOP Concepts
Parameterized - Type
Exceptions
Scala Annotation
Methods
String
Scala Packages
Scala Trait
Collections
Scala Options
Miscellaneous Topics
Higher-order functions (HOFs) are a core concept in functional programming and are prominently featured in Scala. A higher-order function is a function that:
Here are some explanations and examples of higher-order functions in Scala:
A function can take another function as a parameter.
def applyTwice(f: Int => Int, x: Int): Int = f(f(x)) val result = applyTwice(_ * 2, 3) // Result: 12, because (3 * 2) * 2 = 12
In this example, applyTwice
takes a function f
and an integer x
, then applies f
to x
twice.
A function can also return another function.
def multiplier(factor: Int): Int => Int = { x => x * factor } val double = multiplier(2) // 'double' is now a function that doubles its input val result = double(5) // Result: 10
Here, multiplier
returns a function that multiplies its input by a given factor.
Often, when using higher-order functions, especially with collections, we use anonymous (or lambda) functions. These are functions without a name.
val numbers = List(1, 2, 3, 4, 5) val doubled = numbers.map(x => x * 2)
Here, the map
method is a higher-order function that takes a function as its argument.
Scala collections provide many higher-order functions out of the box, often referred to as functional combinators. Some examples include:
map
: Transform each element in the collection.filter
: Retain elements that satisfy a condition.foldLeft
/ foldRight
: Aggregate elements.flatMap
: Map and flatten the result.val numbers = List(1, 2, 3, 4, 5) val sum = numbers.foldLeft(0)((acc, x) => acc + x) // computes the sum
In Scala, you can easily compose two functions to create a new function.
def f(x: Int): Int = x + 1 def g(x: Int): Int = x * 2 val h = f _ compose g // h(x) = f(g(x)) val result = h(3) // Result: 7
You can fix a number of arguments for a given function and produce a new function.
def add(a: Int, b: Int) = a + b val add5 = add(5, _: Int) val result = add5(3) // Result: 8
Here, add5
is a function that adds 5 to its argument.
Higher-order functions are a powerful tool in Scala, allowing you to write expressive, concise, and clean code. They're especially useful in data transformation and processing tasks. Understanding and mastering them is key to effective functional programming in Scala.
Scala functions as first-class citizens:
val square: Int => Int = x => x * x val result = square(5)
Higher-order functions vs. first-order functions in Scala:
// Higher-order function def applyTwice(f: Int => Int, x: Int): Int = f(f(x)) // First-order function def square(x: Int): Int = x * x val result = applyTwice(square, 3)
Function literals and anonymous functions in Scala:
val add: (Int, Int) => Int = (a, b) => a + b val result = add(3, 5)
Passing functions as arguments in Scala:
def applyOperation(f: Int => Int, x: Int): Int = f(x) val result = applyOperation(x => x * x, 4)
Returning functions from functions in Scala:
def multiplier(factor: Int): Int => Int = x => x * factor val multiplyBy3 = multiplier(3) val result = multiplyBy3(7)
Currying and partial application in Scala:
def add(x: Int)(y: Int): Int = x + y val addFive = add(5) _ // Partial application val result = addFive(3)
Higher-order functions with Scala collections:
map
, filter
, and reduce
for powerful and concise operations.val numbers = List(1, 2, 3, 4, 5) val squares = numbers.map(x => x * x)
Map, filter, and reduce functions in Scala:
map
applies a function to each element, filter
selects elements based on a predicate, and reduce
combines elements into a single result.val numbers = List(1, 2, 3, 4, 5) val squares = numbers.map(x => x * x) val evens = numbers.filter(x => x % 2 == 0) val sum = numbers.reduce((x, y) => x + y)
Composing functions in Scala:
val square: Int => Int = x => x * x val double: Int => Int = x => x * 2 val squareAndDouble: Int => Int = square.compose(double) val result = squareAndDouble(3)
Scala higher-order functions and immutability:
val numbers = List(1, 2, 3, 4, 5) val doubledSquares = numbers.map(x => x * x).map(_ * 2)
Function chaining and composition in Scala:
val addOne: Int => Int = _ + 1 val square: Int => Int = x => x * x val result = addOne.andThen(square).apply(3)
Recursion with higher-order functions in Scala:
def factorial(n: Int): Int = if (n <= 1) 1 else n * factorial(n - 1)