50

I started learning scala a few days ago and when learning it, I am comparing it with other functional programming languages like (Haskell, Erlang) which I had some familiarity with. Does Scala has guard sequences available?

I went through pattern matching in Scala, but is there any concept equivalent to guards with otherwise and all?

Cory Klein
  • 51,188
  • 43
  • 183
  • 243
Teja Kantamneni
  • 17,402
  • 12
  • 56
  • 86

4 Answers4

57

Yes, it uses the keyword if. From the Case Classes section of A Tour of Scala, near the bottom:

def isIdentityFun(term: Term): Boolean = term match {
  case Fun(x, Var(y)) if x == y => true
  case _ => false
}

(This isn't mentioned on the Pattern Matching page, maybe because the Tour is such a quick overview.)


In Haskell, otherwise is actually just a variable bound to True. So it doesn't add any power to the concept of pattern matching. You can get it just by repeating your initial pattern without the guard:

// if this is your guarded match
  case Fun(x, Var(y)) if x == y => true
// and this is your 'otherwise' match
  case Fun(x, Var(y)) if true => false
// you could just write this:
  case Fun(x, Var(y)) => false
Nathan Shively-Sanders
  • 18,329
  • 4
  • 46
  • 56
20

Yes, there are pattern guards. They're used like this:

def boundedInt(min:Int, max: Int): Int => Int = {
  case n if n>max => max
  case n if n<min => min
  case n => n
}

Note that instead of an otherwise-clause, you simply specifiy the pattern without a guard.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • What will be the `n` in this case and please give an working example for the above. – Jet Aug 01 '16 at 05:00
  • 2
    @Jet `n` will be the argument given to the function. [Here](http://ideone.com/HhSuF0)'s an example of using the function. – sepp2k Aug 01 '16 at 15:42
9

The simple answer is no. It is not exactly what you are looking for (an exact match for Haskell syntax). You would use Scala's "match" statement with a guard, and supply a wild card, like:

num match {
    case 0 => "Zero"
    case n if n > -1 =>"Positive number"
    case _ => "Negative number"
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shaun
  • 3,928
  • 22
  • 21
4

I stumbled to this post looking how to apply guards to matches with multiple arguments, it is not really intuitive, so I am adding an random example here.

def func(x: Int, y: Int): String = (x, y) match {
  case (_, 0) | (0, _)  => "Zero"
  case (x, _) if x > -1 => "Positive number"
  case (_, y) if y <  0 => "Negative number"
  case (_, _) => "Could not classify"
}

println(func(10,-1))
println(func(-10,1))
println(func(-10,0))
cevaris
  • 5,671
  • 2
  • 49
  • 34