views:

555

answers:

2

Is it possible to match on a comparison using the pattern matching system in Scala? For example:

a match {
    case 10 => println("ten")
    case _ > 10 => println("greater than ten")
    case _ => println("less than ten")
}

The second case statement is illegal, but I would like to be able to specify "when a is greater than".

+19  A: 

You can add a "pattern guard", i.e. an if and a boolean expression after the pattern:

a match {
    case 10 => println("ten")
    case x if x > 10 => println("greater than ten")
    case _ => println("less than ten")
}

Edit: Note that this is more than superficially different to putting an if after the =>, because a pattern won't match if the guard is not true.

Ben James
Ben, good answer, it really illustrates the importance of pattern guard.
JeffV
+3  A: 

As a non-answer to the question's spirit, which asked how to incorporate predicates into a match clause, in this case the predicate can be factored out before the match:

def assess(n: Int) {
  println(
    n compare 10 match {
      case 0 => "ten"
      case 1 => "greater than ten"
      case -1 => "less than ten"
    })
}

Now, the documentation for RichInt.compare(Int) promises only that the non-equal outcomes will be greater than or less than zero. Java's Comparable#compareTo(T) is specified similarly to Scala's. It happens to be conventional to use 1 and -1 for the positive and negative values, respectively, as Scala's current implementation does, but one can't make such an assumption without some risk of the implementation changing out from underneath.

seh
I'm not sure if you're suggesting this as a real solution, but I would strongly recommend against anything that relies on an undocumented convention or assumption.
Ben James
Exactly. That's why I wrote "one can't make such an assumption without some risk", and qualified my answer as a "non-answer". It's interesting to consider *why* `compare()` and `compareTo()` don't specify 0, 1, and -1 as their codomain.
seh