October 1, 2025

Scala – Algebraic Data Types (ADT)

In this tutorial, you will learn about the very important concept of Algebraic Data Types (ADT) in Scala.

Let’s begin with what we already know, enum or enumeration types.

  1. Enumerations Types
  2. What are ADTS
  3. Sum Types (Union Types)
  4. Pattern Matching on ADTs

 

1. Enumeration Types

An enumeration is used to define a data type that consists of a set of named values. All the value in an enumeration share a unique type known as Value type member of the enumeration.

Creating Enums in Scala

To create a enum type in Scala, we need to create an object that extends the Enumeration type. This is because Scala does not provide an enum keyword.

The code below creates an enum type names Size with three values: Small, Medium and Large

object Sizes extends Enumeration {
  type Sizes = Value
  val Small, Medium, Large = Value
}

 

You can print the string value of enumeration using  the code below:

println(s"My size is ${Size.Medium}")

 

Pattern Matching on Enum Values

Although we’ll talk about pattern matching in a different tutorial, the code below shows how to perform some operation base on pattern matching on values of an enum.

Size.values.foreach {
  case s if (s == Size.Small ) => {
    println(s)
  }
  case s if (s == Size.Medium) => {
    println(s)
  }
  case s if (s == Size.Large) => {
    println(s)
  }
}

 

2. Algebraic Data Types

In theory, algebra can be viewed as:

  • a set of objects
  • as set of operations that can be applied to those objects to create new objects

For example, we can apply a set of arithmetic operations (+, -, * and /) to a set of numbers to produce new numbers.

In Scala, we can apply certain operation to a set of types to produce  new type(s).

Let’s create a new type called Weather from a set of objects: Windy, Cloudy, Rainy and Overcast

sealed  trait Weather

case object Rainy extends Weather
case object Windy extends Weather
case object Cloudy extends Weather
case object Overcast extends Weather

 

The sealed trait means that only these four values defined here can extend the Weather type. Let’s now talk about a specific algebraic data type: the sum type

 

3. The Sum Type (Union Type)

The Sum type helps us define a type that can have certain values. With the sum type, we enumerate all the possible instances of a type. The following are important to know about the sum type:

  • they are create with a sealed trait as  the base type
  • the individual instances are created as case objects
  • the “is-a” relationship is used for describing the sum type
  • instances of the sum type can be parameterized

In the code below, we define an Employee type which could be either a Doctor, Driver or Intern. This is represented below:

  • Doctor has two parameter: name: String and specialty: String
  • Driver has two parameter: name: String and assignedCar: String
  • Intern has one parameter: age

The equivalent Scala code is given below:

sealed trait Employee
  case class Doctor(name:String, specialty: String) extends Employee
  case class Driver(name:String, assignedCar: String) extends Employee
  case class Intern(name:String, age: Int)extends Employee

Now you that you understand ADTs, you can create a couple more just to get used to it.

 

4. Pattern Matching With ADTs

Pattern matching allows us to decompose a specified ADT using the extractor method. With it, we can extract the fields of an ADT. This means that the case classed would have to implement unapply method to be an extractor.

Let’s define a pattern match for our Employee ADT

def isEmployee(e: Employee) : Boolean = e match {
  case Doctor(name, specialty) => true
  case Driver(name, assignedCar) =>true
  case Intern(name, age) => false
}

 

In the case of pattern matching code above, we define a function that takes an Employee object and returns a boolean depending on the particular instance.

 

Leave a Reply