Friday, 2 October 2015

Sequence of cases in scala

 There's not much said about sequences of cases (sequence of cases) in the "Programming in Scala: second edition". Googling returns a bit different stuff. Essentially they are just more concise way to define match cases and they not only work with Option, but with any other types as well. The code below can describe usage of sequences of cases:

var capitals = Map("France"->"Paris", "Japan"->"Tokyo", "Russia"->"Moscow")

/* sequence of cases */
val withDefaultSequenceOfCases: Option[String] => String = {
  case Some(x) => x // pattern match to extract string from Some
  case None => "?"
}// withDefaultSequenceOfCases: Option[Int] => Int = <function1>

/* match representation of sequence of cases */
def withDefaultMatch(s: Option[String]): String = s match {
  case Some(x) => x
  case None => "?"
}// withDefaultMatch: Option[String] => String = <function1>

capitals get "Russia" //res0: Option[String] = Some(Moscow)
capitals get "Sumatra" //Option[String] = None
capitals("Russia") //String = Moscow
withDefaultSequenceOfCases(Some("Test")) //String = Test
withDefaultSequenceOfCases(capitals get "Japan") //String = Tokyo
withDefaultMatch(capitals get "France") //String = Paris
withDefaultSequenceOfCases(capitals get "Somewhere") //String = ?
withDefaultMatch(capitals get "Pacific") //String = ?

/* sequence of cases is not necessarily Option */
abstract class Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr

val renderUnary: Expr => String = {
  case UnOp(op, arg:Number) => op+""+arg.num
  case UnOp(op, arg) => op+""+arg
  case _ => "non unary operator"
}

renderUnary(UnOp("-",Number(1))) //String = -1.0
renderUnary(UnOp("+",Number(2))) //String = +2.0
renderUnary(Number(1)) //String = not unary operator