Reference ยท Functional Programming in Scala

Functional data structures

The compact reference for Lesson 03.

Standalone

These examples use a tiny immutable list and small values. No VPS, account, private repository, production data, network service, or CLI is required.

Optional Scala source for syntax comparison.

Two constructors

sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]

Pattern matching

def sum(xs: List[Int]): Int = xs match {
  case Nil => 0
  case Cons(head, tail) => head + sum(tail)
}

Match the empty base case first, then expose the head and recurse over the tail.

Safe sharing

def tailOrEmpty[A](xs: List[A]): List[A] = xs match {
  case Nil => Nil
  case Cons(_, tail) => tail
}

def setHead[A](xs: List[A], value: A): List[A] = xs match {
  case Nil => Cons(value, Nil)
  case Cons(_, tail) => Cons(value, tail)
}

setHead allocates one new node and reuses the old tail. Immutability means the shared suffix cannot be changed behind another reference.

Fold and map

def foldRight[A, B](xs: List[A], zero: B)(f: (A, B) => B): B = xs match {
  case Nil => zero
  case Cons(head, tail) => f(head, foldRight(tail, zero)(f))
}

def map[A, B](xs: List[A])(f: A => B): List[B] =
  foldRight(xs, Nil: List[B])((head, tail) => Cons(f(head), tail))

Design checklist

  1. List every constructor case.
  2. Choose the base result for the empty case.
  3. Make the recursive call on a smaller structural value.
  4. Return new nodes instead of mutating old ones.
  5. Share immutable suffixes when that preserves the desired shape.

Rust translation

Think of Nil/Cons as the Scala equivalent of Empty/Cons enum variants. The ownership and allocation details differ, but the case analysis and recursive structure transfer directly.