Skip to content
On this page

Pattern maching

Scala uses the keywords match and case as well as the => notation to achieve pattern matching. A pattern matching block is evaluated as any other block, hence it have a return value and type.

NB: the _ case is used as the default case.

scala
def writtenInt(x: Int): String =
    x match
        case 1 => "one"
        case 2 => "two"
        case 3 => "three"
        case _ => "other"

println(writtenInt(1))      // prints "one"
println(writtenInt(3))      // prints "three"
println(writtenInt(4))      // prints "other"

Matching on case classes

Case classes are especially useful for pattern matching as their class members can be extracted directly.

scala
sealed abstract class Message

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

def printMessage(m: Message): Unit =
    m match
		case Email(sender, title, body) =>
            println(s"From: <$sender>") 
            println(s"Subject: $title")
            println(body) 
		case SMS(caller, message) =>
            println(s"$caller: $message")

printMessage(Email("alice@gmail.com", "News from Australia", "Hi Bob, [...], see you soon!"))
printMessage(SMS("Bob", "Hi Alice, thanks for the mail!"))

Outputs:

From: <alice@gmail.com>
Subject: <News from Australia>     
Hi Bob, [...], see you soon!  

Bob: Hi Alice, thanks for the mail!

Matching on type

Scala lets you matching on type only:

NB: the _ used in the example bellow is not the same as seen previously. It only means that we do not care about the instance matched.

scala
def sendNotification(m: Message): Unit =
    m match
		case e: Email => println("You received a mail")
		case _: SMS => println("You received a SMS")

Pattern guards

Pattern guards are boolean expressions which are used to make cases more specific. Just add if <boolean expression> after the pattern.

scala
def writtenInt(x: Int)(allowOdd: Boolean): String =
    x match
        case 1 if allowOdd => "one"
        case 2 => "two"
        case 3 if allowOdd => "three"
        case _ => "other"

println(writtenInt(1)(true))        // prints "one"
println(writtenInt(3)(false))       // prints "other"
println(writtenInt(4)(false))       // prints "other"

Released under the MIT License.