Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala pattern match default guards

I want to do many case statements with same guard in front of each. Can I do it in way that doesn't require code duplication ?

"something" match {
   case "a" if(variable) => println("a")
   case "b" if(variable) => println("b")
   // ...
 }
like image 734
Lukasz Avatar asked Aug 17 '12 13:08

Lukasz


People also ask

What is the default option in a match case in Scala?

getList("instance").

How do you match a pattern in Scala?

A pattern match includes a sequence of alternatives, each starting with the keyword case. Each alternative includes a pattern and one or more expressions, which will be evaluated if the pattern matches. An arrow symbol => separates the pattern from the expressions.

Does Scala have pattern matching?

Notes. Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.

What is case _ in Scala?

case _ => does not check for the type, so it would match anything (similar to default in Java). case _ : ByteType matches only an instance of ByteType . It is the same like case x : ByteType , just without binding the casted matched object to a name x .


3 Answers

You could create an extractor:

class If {
  def unapply(s: Any) = if (variable) Some(s) else None
}
object If extends If
"something" match {
  case If("a") => println("a")
  case If("b") => println("b")
  // ...
}
like image 131
Daniel C. Sobral Avatar answered Oct 16 '22 03:10

Daniel C. Sobral


It seems that the OR (pipe) operator has higher precedence than the guard, so the following works:

def test(s: String, v: Boolean) = s match {
   case "a" | "b" if v => true
   case _ => false
}

assert(!test("a", false))
assert( test("a", true ))
assert(!test("b", false))
assert( test("b", true ))
like image 43
0__ Avatar answered Oct 16 '22 04:10

0__


0__'s answer is a good one. Alternatively You can match against the "variable" first:

variable match {
  case true => s match {
    case "a" | "b" | "c" => true
    case _ => false
  }
  case _ => false
}
like image 34
Eun Woo Song Avatar answered Oct 16 '22 05:10

Eun Woo Song