packages

Basic idea

Take the idea of a simple case-switch and put it on Steroids. Sure you can do basic stuff like check user input and such. But with the power of Scala you can take it a step further and it can decompose the value into separate parts and then bind them to variables.

val ch = '+'
var sign: Integer = 0
sign = ch match {
  case '+'  => 1
  case '-'  => -1
  case _ => 0
}

The keyword match checks ch against the case statements and sets values. Notice the _ that match hits if nothing else matches above. It is there to ensure a value is set for the cases.

Type Matches

You can match a class type and then invoke specific behavior on the instance. With a few lines of code you can fluidly control complex behaviors using this technique.

abstract class Appliance
case class Fridge(freezing_temperature: Double) extending Appliance {
  def changeTemp = "Temp Changing"
}
case class Washer(number_of_cycles: Int) extending Appliance {
  def changeCyleNumber = "Changing Cycle Number"
}

def makeChange(appliance: Appliance) = appliance match {
  case f: Fridge => f.changeTemp
  case w: Washer => w.changeCyleNumber
}

With Case Classes

These are classes that work specifically well with Scala’s Pattern Matching mechanism.

abstract class Appliance
case class Fridge(freezing_temperature: Double) extending Appliance
case class Washer(number_of_cycles: Int) extending Appliance
case class Generator(duration_in_hours: Int) extending Appliance

Pay close attention to Appliance with the code above we can now do:

def showDescription(description: Description): String = {
  description match {
    case Fridge(freezing_temperature) =>
      s"Fridge freezing_temperature is $freezing_temperature"
    case Washer(number_of_cycles) =>
      s"Washer has $number_of_cycles as number_of_cycles"
    case Generator(duration_in_hours) =>
      s"Generator can run for $duration_in_hours hours"
  }


  val fridge = Fridge(0.0) # new() not needed!
  println(showDescription(fridge)) # 'Fridge freezing_temperature is 0.0'

Using this class wrapper around some functionality and using pattern matching is powerful and solves many syntax issues in one fell swoop.

With Pattern Guards

In case the matching is too generic you can add guards to narrow down the matching. Guards are boolen checks that are added following the matched case.

def showSpanishDescription(description: Description): String = {
  description match {
    case Fridge(freezing_temperature) if localeInLatinAmerica =>
      s"Refrigerador freezing_temperature es $freezing_temperature"
    case Washer(number_of_cycles) if localeInLatinAmerica =>
      s"La lavadora tiene $number_of_cycles como number_of_cycles"
    case other =>
        showDescription(other)
  }