0Pricing
Scala for Backend Engineering & Functional Programming · Lesson

Folding and Reducing

foldLeft and reduce.

Folding and Reducing is a free Scala for Backend Engineering & Functional Programming lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Scala for Backend Engineering & Functional Programming learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Combining elements into one

Sometimes you need to combine all elements of a collection into a single value, like a sum or a concatenation. Scala provides fold, foldLeft, foldRight, and reduce for this.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4)
    println(nums.sum)
    println(nums.product)
  }
}

reduce: combine without a seed

reduce combines elements pairwise using a binary function. It needs at least one element, otherwise it throws an exception.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4)
    val total = nums.reduce((a, b) => a + b)
    println(total)
    val max = nums.reduce((a, b) => if (a > b) a else b)
    println(max)
  }
}

foldLeft: combine with a seed

foldLeft takes an initial seed value and a function. It is safe on empty collections (returns the seed) and lets the result type differ from the element type.

Syntax: xs.foldLeft(seed)((acc, x) => ...).

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4)
    val sum = nums.foldLeft(0)((acc, x) => acc + x)
    println(sum)
    val empty = List.empty[Int].foldLeft(0)(_ + _)
    println(empty)
  }
}

The accumulator pattern

In a fold, the first argument is the accumulator that carries the running result, and the second is the current element. Each step updates the accumulator.

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("Scala", "is", "great")
    val sentence = words.foldLeft("")((acc, w) => acc + w + " ")
    println(sentence.trim)
  }
}

Result type can differ

A powerful feature of foldLeft: the accumulator type can differ from the elements. Here we fold a list of numbers into a String.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3)
    val joined = nums.foldLeft("nums:")((acc, n) => acc + " " + n)
    println(joined)
  }
}

foldRight: from the right

foldRight processes elements from right to left. The accumulator is the second argument: (x, acc) => .... Direction matters for non-commutative operations.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4)
    val left = nums.foldLeft("")((acc, x) => acc + x)
    val right = nums.foldRight("")((x, acc) => acc + x)
    println("foldLeft:  " + left)
    println("foldRight: " + right)
  }
}

Left vs right and performance

foldLeft is tail-recursive and stack-safe on large lists. foldRight on a List can overflow the stack for very large inputs. Prefer foldLeft unless order forces otherwise.

object Main {
  def main(args: Array[String]): Unit = {
    val big = (1 to 100000).toList
    val total = big.foldLeft(0L)((acc, x) => acc + x)
    println(total)
  }
}

Building a collection with fold

Folds are general enough to build collections. Here we reverse a list by prepending each element to an accumulator list.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4)
    val reversed = nums.foldLeft(List.empty[Int])((acc, x) => x :: acc)
    println(reversed)
  }
}

reduceOption for safety

Because reduce fails on empty collections, reduceOption returns an Option instead: Some(result) when non-empty, None when empty.

object Main {
  def main(args: Array[String]): Unit = {
    println(List(3, 1, 4).reduceOption(_ + _))
    println(List.empty[Int].reduceOption(_ + _))
  }
}

fold: a symmetric variant

fold is like foldLeft but the accumulator must be the same type as the elements. It is often used with parallel collections.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4)
    val total = nums.fold(0)(_ + _)
    println(total)
  }
}

Counting with foldLeft

Folds can compute richer results, like counting how many elements satisfy a condition, all in one pass.

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(4, 7, 2, 9, 6, 1)
    val evenCount = nums.foldLeft(0)((acc, x) => if (x % 2 == 0) acc + 1 else acc)
    println(s"even numbers: $evenCount")
  }
}

Quick Check

What is the key difference between reduce and foldLeft?

Recap

You learned folding and reducing:

  • reduce — combine pairwise, no seed, fails if empty
  • reduceOption — safe variant returning Option
  • foldLeft — seed + accumulator, stack-safe, flexible result type
  • foldRight — right-to-left, watch the stack on large lists
  • Folds can even build new collections

Frequently asked questions

Is the “Folding and Reducing” lesson free?

Yes — the full text of “Folding and Reducing” is free to read here on the web, and the Scala for Backend Engineering & Functional Programming course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Scala for Backend Engineering & Functional Programming course, upgrade to CoddyKit PRO.

What will I learn in “Folding and Reducing”?

foldLeft and reduce. You practise Scala for Backend Engineering & Functional Programming with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Scala for Backend Engineering & Functional Programming?

No prior experience is required. Scala for Backend Engineering & Functional Programming on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Folding and Reducing” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Scala for Backend Engineering & Functional Programming lesson?

Yes. Every Scala for Backend Engineering & Functional Programming lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. List, Vector, Set, Map
  2. Transformations
  3. Folding and Reducing
  4. Grouping and Sorting
← Back to Scala for Backend Engineering & Functional Programming