16

If I have a match expression, how can I make it automatically ignore a non-match without explicitly doing case _ =>? Is there a way to create a function that does something like this maybe?

ryeguy
  • 65,519
  • 58
  • 198
  • 260

3 Answers3

29

You need a generic way to handle "ignoring". Options, among other classes, provide this (among other things). So you can:

val i = 7
Some(i) collect {
  case 3 => "Yay!"
  case 5 => "Boo!"
}

to get None (typed as an Option[String]). So basically, if you change x match to Some(x) collect you get the functionality you want. It is better to do this when one is comfortable with handling options.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • Scala3 it seems, is tighter hence complains on collect similarly as with match. –  Jul 12 '21 at 11:40
11

Write a generic matcher:

object Match {
    def default: PartialFunction[Any, Unit] = { case _ => }
    def apply[T](x: T)(body: PartialFunction[T, Unit]) = (body orElse default)(x)
}

Example:

scala> 1 to 5 foreach (Match(_) {
     |   case 2 => println("two")
     |   case 3 => println("three")
     | }
     | )
two
three

You might be interested too in PartialFunction's companion object's methods cond and condOpt.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
2

Any match block that can't handle all possible input values forms a Partial Function, which is absolutely possible to define and use in Scala.

PartialFunction is a subclass of Function, and adds the isDefinedAt method, which returns true if it has a defined match for the supplied value. Partial Functions are best used in places that test for definition, such as catch blocks or the collect method in the 2.8 collections API. Otherwise, you'll get an exception if you try to call it with a value that isn't defined as an input.

Kevin Wright
  • 49,540
  • 9
  • 105
  • 155