Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala enumeration type fail in match/case

Enumerated values seem to fail in match/case expressions. This is what happens in a worksheet.

  object EnumType extends Enumeration {
    type EnumType = Value
    val a, b = Value
  }

  import EnumType._
  val x: EnumType = b                //> x : ... .EnumType.EnumType = b

  x match {
    case a => "a"
    case b => "b"
  }                                  //> res0: String = a

  if (x == a) "a" else "b"           //> res1: String = b

What's going on? Thanks.

like image 413
RussAbbott Avatar asked Jan 28 '14 17:01

RussAbbott


3 Answers

Like @Kevin Wright and @Lee just said, a and b work as variable patterns, not as EnumType values.

Another option to fix your code is making it explicit you are referencing values from the EnumType singleton:

scala> x match { case EnumType.a => "a" case EnumType.b => "b" }
res2: String = b
like image 86
rsenna Avatar answered Nov 17 '22 13:11

rsenna


The a and b in your match block aren't the same as the enumerated values a and b, the pattern matcher will simply match x in the first case and bind it to a new value a (the second case will be ignored)

To avoid this, you have two choices:

1) wrap the values in backticks:

x match {
  case `a` => "a"
  case `b` => "b"
}     

2) Make the enumerated values uppercase:

object EnumType extends Enumeration {
  type EnumType = Value
  val A, B = Value
}

import EnumType._
val x: EnumType = B

x match {
  case A => "a"
  case B => "b"
}   

Given that these values are (to all intents an purposes) constants, using uppercase is the more common/idiomatic solution.

Note that only the initial letter needs to be uppercase, not the name of the entire literal.

like image 39
Kevin Wright Avatar answered Nov 17 '22 11:11

Kevin Wright


a in your case statement is an unbound variable which matches anything. You need to explicitly check the value is equal to a:

x match {
    case v if v == a => "a"
    case _ => "b"
}
like image 3
Lee Avatar answered Nov 17 '22 11:11

Lee