0Pricing
Scala for Backend Engineering & Functional Programming · Lesson

Sealed Traits

Closed hierarchies.

Sealed Traits is a free Scala for Backend Engineering & Functional Programming lesson on CoddyKit — lesson 2 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.

What Is a Trait?

A trait is like an interface: it declares a common type that other classes can extend.

Traits let you group related types under one umbrella so they can be used interchangeably.

A Basic Trait

Declare a trait with trait, then have classes or objects extends it.

trait Shape
case class Circle(r: Double) extends Shape
case class Square(side: Double) extends Shape
object Main {
  def main(args: Array[String]): Unit = {
    val s: Shape = Circle(2.0)
    println(s)
  }
}

What Does sealed Mean?

A sealed trait can only be extended by types declared in the same file.

This closes the hierarchy: the compiler knows the complete list of possible subtypes.

sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
object Main {
  def main(args: Array[String]): Unit = {
    val c: Color = Green
    println(c)
  }
}

Case Objects as Variants

When a variant has no data, use case object instead of case class. There is only ever one instance.

This is perfect for enum-like values.

sealed trait Direction
case object North extends Direction
case object South extends Direction
object Main {
  def main(args: Array[String]): Unit = {
    val d: Direction = North
    println(d)
  }
}

Mixing Objects and Classes

A sealed trait can have both case object variants (no data) and case class variants (with data).

sealed trait Event
case object Started extends Event
case class Failed(reason: String) extends Event
object Main {
  def main(args: Array[String]): Unit = {
    val e: Event = Failed("timeout")
    println(e)
  }
}

Matching on a Sealed Trait

You match on the trait and handle each variant. Because the hierarchy is sealed, the compiler can verify you covered them all.

sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
object Main {
  def hex(c: Color): String = c match {
    case Red   => "#FF0000"
    case Green => "#00FF00"
    case Blue  => "#0000FF"
  }
  def main(args: Array[String]): Unit = {
    println(hex(Green))
  }
}

Compiler Warnings

If you forget a variant in a match over a sealed trait, the compiler warns you about the missing case.

This catches bugs when you later add a new variant. We will explore this fully in the exhaustive matching lesson.

Traits Can Declare Members

A trait can declare methods or fields that all subtypes share or must implement.

sealed trait Animal {
  def sound: String
}
case object Dog extends Animal { def sound = "Woof" }
case object Cat extends Animal { def sound = "Meow" }
object Main {
  def main(args: Array[String]): Unit = {
    println(Dog.sound)
    println(Cat.sound)
  }
}

Why Sealed?

Sealing a trait gives you:

  • A known, closed set of subtypes
  • Exhaustiveness checking in match
  • Safer refactoring when adding variants

Sealed traits plus case classes are how Scala builds algebraic data types.

Using the Hierarchy

Functions can accept the trait type and work with any variant, dispatching via pattern matching.

sealed trait Payment
case class Cash(amount: Int) extends Payment
case class Card(number: String) extends Payment
object Main {
  def summary(p: Payment): String = p match {
    case Cash(a) => s"cash $a"
    case Card(n) => s"card ending ${n.takeRight(4)}"
  }
  def main(args: Array[String]): Unit = {
    println(summary(Cash(50)))
    println(summary(Card("123456789012")))
  }
}

Putting It Together

A sealed trait with mixed variants, shared via a function that matches each case.

sealed trait Result
case object Pending extends Result
case class Success(value: Int) extends Result
case class Error(msg: String) extends Result
object Main {
  def show(r: Result): String = r match {
    case Pending    => "waiting"
    case Success(v) => s"ok: $v"
    case Error(m)   => s"fail: $m"
  }
  def main(args: Array[String]): Unit = {
    List(Pending, Success(7), Error("boom")).foreach(r => println(show(r)))
  }
}

Quick Check

Test your understanding of sealed traits.

Recap

You learned about sealed traits:

  • A trait defines a shared supertype
  • sealed limits subtypes to the same file
  • Use case object for data-less variants, case class for variants with data
  • Sealing enables exhaustiveness checking in match

Frequently asked questions

Is the “Sealed Traits” lesson free?

Yes — the full text of “Sealed Traits” 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 “Sealed Traits”?

Closed hierarchies. 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 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Sealed Traits” 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. Case Classes
  2. Sealed Traits
  3. Algebraic Data Types
  4. Exhaustive Matching
← Back to Scala for Backend Engineering & Functional Programming