What is a sealed trait?

100,071

Solution 1

A sealed trait can be extended only in the same file as its declaration.

They are often used to provide an alternative to enums. Since they can be only extended in a single file, the compiler knows every possible subtypes and can reason about it.

For instance with the declaration:

sealed trait Answer
case object Yes extends Answer
case object No extends Answer

The compiler will emit a warning if a match is not exhaustive:

scala> val x: Answer = Yes
x: Answer = Yes

scala> x match {
     |   case No => println("No")
     | }
<console>:12: warning: match is not exhaustive!
missing combination            Yes

So you should use sealed traits (or sealed abstract class) if the number of possible subtypes is finite and known in advance. For more examples you can have a look at list and option implementations.

Solution 2

a sealed trait is the same as a sealed class ?

As far as sealed goes, yes. They share the normal differences between trait and class, of course.

Or, if not, what are the differences ?

Moot.

When is it a good idea to use a sealed trait (and when not) ?

If you have a sealed class X, then you have to check for X as well as any subclasses. The same is not true of sealed abstract class X or sealed trait X. So you could do sealed abstract class X, but that's way more verbose than just trait and for little advantage.

The main advantage of using an abstract class over a trait is that it can receive parameters. That advantage is particularly relevant when using type classes. Let's say you want to build a sorted tree, for instance. You can write this:

sealed abstract class Tree[T : Ordering]

but you cannot do this:

sealed trait Tree[T : Ordering]

since context bounds (and view bounds) are implemented with implicit parameters. Given that traits can't receive parameters, you can't do that.

Personally, I prefer sealed trait and use it unless some particular reason makes me use a sealed abstract class. And I'm not talking about subtle reasons, but in-your-face reasons you cannot ignore, such as using type classes.

Solution 3

From the daily-scala blog:

When a trait is "sealed" all of its subclasses are declared within the same file and that makes the set of subclasses finite which allows certain compiler checks.

Solution 4

Also I feel the need to point you to the specifications:

The sealed modifier applies to class definitions. A sealed class may not be directly inherited, except if the inheriting template is defined in the same source file as the inherited class. However, subclasses of a sealed class can be inherited anywhere.

M. Odersky. The Scala language specification, version 2.8. online, Sept., 2013.

Solution 5

‌‌Briefly:

  • Sealed traits can only be extended in the same file
  • List this lets the compiler easily know all possible subtypes
  • Use sealed traits when the number of possibly subtypes is finite and known in advance
  • A way of creating something like enum in Java
  • Help to define algebraic data types (ADTs)

and for more details Everything about sealed traits in Scala

Share:
100,071
John Threepwood
Author by

John Threepwood

Primary interests: Logic, Java/C#, C/C++. If you wish to get in contact, please email me: firstname.lastname at GMAIL

Updated on July 08, 2022

Comments

  • John Threepwood
    John Threepwood almost 2 years

    Sealed classes are described in 'Programming in Scala', but sealed traits are not. Where can I find more information about a sealed trait?

    I would like to know, if a sealed trait is the same as a sealed class? Or, if not, what are the differences? When is it a good idea to use a sealed trait (and when not)?