October 3, 2025

Scala – Pattern Matching

Pattern matching allows you to check a value against a given pattern. It is similar to Java and C++ switch statement, but it’s more powerful.

The syntax for Scala pattern matching is given below:

val scores = Seq(30, 50, 60, 90)
val score = scores(Random.nextInt(scores.length))  score match {
  case 30 => "F - Fail"
  case 50 => "C - Good"
  case 60 => "B - Very Good"
  case 90 => "A - Excellent"
}

 

In the example, we create a value, score, that gets a random number taken from a sequence of four integers 30, 50, 60 and 90. score now becomes the left operand of the match operator and on the right we have an expression with four cases. Also note the the match expression is a value that can be assigned.

  1. Matching Case Classes
  2. Matching on Types Only

 

1. Matching Case Classes

Pattern matching is normally applied in case classes. Let’s assume we have this representation:

type  Message =
      Email String String String
    | SMS String String
    | AudioMemo String String
    | Letter

This is and Elm syntax. You can learn Elm here.

The means that we have four classes: Email, SMS, AudioMemo and Letter. All of them are derived from Message. Also, the parameters for the classes are specified against each of them.

The Scala equivalent for this is given below:

sealed trait Message

case class Email (sender:String, title: String, body: String) extends Message
case class SMS (caller:String, message: String) extends Message
case class AudioMemo (contact:String, link: String) extends Message
case class Letter() extends Message

 

Now, we would like to display a custom message based on the particular class. Therefore we would do pattern matching on the base class, Message. We’ll write a function that would take an argument of type Message and display a particular output based on which implementation of message it is.

The function is given below:

def showMessage = (a: Message) => {
  a match {
    case Email(sender, title, _) => {
      println(s"You received a mail from $sender with $title")
    }
    case SMS(caller, message) => {
      println(s"An SMS arrived from $caller. Message: $message")
    }
    case AudioMemo(name, link) => {
      println(s"Audio message from $name available here: $link")
    }
    case Letter() => {
      println("Please check your postbox")
    }
  }
}

 

Now we can call the function by and pass in a message type like so:

val myMail = new Email("Kindson", "Hello", "Love you" )
showMessage(myMail)

val myLetter = new Letter()
showMessage(myLetter)

I recommend you run this code yourself and see what the output looks like.

 

2. Matching on Only Types

In the example given in the preceding section, did pattern matching on the types as well as the arguments. But we can also perform pattern matching based on only the types. The code below illustrates that. Assuming we have two case classes Phone and Tablet that extends Device as shown below.

sealed trait Device

case class Phone(make: String) extends Device
case class Tablet(make: String) extends Device
case class Laptop(make: String) extends Device

 

Now we write a function that returns a string based on the implementation of the device. Note the structure of the case statement that no argument was used

 def tellMe(device: Device) = device match {
   case  p:Phone => "This is a phone"
   case t:Tablet => "This is a tablet"
   case l:Laptop => "This is a laptop"
 }

 

Leave a Reply