An example of using enums in Scala 3 (Dotty)

Here’s a quick example of how to use Scala 3 enums, including using them as constructor and method parameters, and in a match expression. If you’ve read the Scala Cookbook or Functional Programming, Simplified, you might recognize my usual “pizza store” example.

The Scala 3 enums

First, here are a few Scala 3 enums for my pizza store application:

enum CrustSize:
   case Small, Medium, Large

enum CrustType:
   case Thin, Thick, Regular

enum Topping:
   case Cheese, Pepperoni, Olives

Compared to Scala 2

Notice how much more concise this is than your ADT modeling choice in Scala 2:

// scala 2.x
sealed trait Topping
case object Cheese extends Topping
case object Pepperoni extends Topping
case object Sausage extends Topping
case object Mushrooms extends Topping
case object Onions extends Topping

sealed trait CrustSize
case object SmallCrustSize extends CrustSize
case object MediumCrustSize extends CrustSize
case object LargeCrustSize extends CrustSize

sealed trait CrustType
case object RegularCrustType extends CrustType
case object ThinCrustType extends CrustType
case object ThickCrustType extends CrustType

enums as constructor parameters

Next, you can use the enums as constructor parameters:

case class Pizza (
   crustSize: CrustSize,
   crustType: CrustType,
   toppings: Seq[Topping]
)

enums as method parameters and in match expressions

You can also use enums as method parameters and in Scala 3 match expressions:

def printCrustSize(cs: CrustSize) = cs match {
   case Small  => println("small")
   case Medium => println("medium")
   case Large  => println("large")
}

Sample app

Given that setup, here’s an example of how to create a couple of pizzas in a sample application:

object DottyEnums extends App {

    import CrustSize.*
    import CrustType.*
    import Topping.*
    
    val smallThinCheesePizza = Pizza(
       Small, Thin, Seq(Cheese)
    )

    val largeThickWorks = Pizza(
       Large, Thick, Seq(Cheese, Pepperoni, Olives)
    )

    println(smallThinCheesePizza)
    println(largeThickWorks)

}

I hope that gives you a little idea of how you’ll be able to use enums in Scala 3. (For more information, see the Dotty Enumerations page.)

The complete example application

If you want to experiment with that code on your own system, here’s the complete Scala 3 source code:

enum CrustSize {
   case Small, Medium, Large
}

enum CrustType {
   case Thin, Thick, Regular
}

enum Topping {
   case Cheese, Pepperoni, Olives
}


case class Pizza (
   crustSize: CrustSize,
   crustType: CrustType,
   toppings: Seq[Topping]
)


object DottyEnums extends App {

    import CrustSize.*
    import CrustType.*
    import Topping.*
    
    // passing enums as method parameters
    val smallThinCheesePizza = Pizza(
        Small, Thin, Seq(Cheese)
    )

    val largeThickWorks = Pizza(
        Large, Thick, Seq(Cheese, Pepperoni, Olives)
    )

    println(smallThinCheesePizza)
    println(largeThickWorks)

    // using an enum as a method parameter and in a match expression
    printCrustSize(Small)
    def printCrustSize(cs: CrustSize) = cs match {
        case Small  => println("small")
        case Medium => println("medium")
        case Large  => println("large")
    }

}

If you haven’t used Scala 3 before, I wrote this short article, How to create a Scala 3 (Dotty) project with SBT, which can help you create a Dotty/SBT project to test this code with.

All the best,
Al