Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern Match "return" value

Why is it not possible to chain pattern matching constructs? For instance, the following is legal, if nonsensical,

val a = ADT(5)

val b = a match {
  case ADT(a) if a > 4 => ADT(a * 3)
  case ADT(a) => ADT(a + 1)
} 
b match {
  case ADT(a) if a > 13 => doSomething(a)
  case _ => {}
}

but the following is not:

a match {
  case ADT(a) if a > 4 => ADT(a * 3)
  case ADT(a) => ADT(a + 1)
} match {
  case ADT(a) if a > 13 => doSomething(a)
  case _ => {}
}

I suspect it's because I shouldn't be doing it in the first place, but in principle I don't see why it's not legal.

like image 780
Carl Summers Avatar asked May 04 '13 04:05

Carl Summers


People also ask

How does pattern matching work?

Pattern Matching works by "reading" through text strings to match patterns that are defined using Pattern Matching Expressions, also known as Regular Expressions. Pattern Matching can be used in Identification as well as in Pre-Classification Processing, Page Processing, or Storage Processing.

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.

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 .

Which method of case class allows using objects in pattern matching?

Case classes are Scala's way to allow pattern matching on objects without requiring a large amount of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be pattern matchable.


2 Answers

Yes it should work, because (almost) everything in Scala is an expression and every expression can be used as a pattern match.

In this case the pattern match is an expression, so it can be used by another "chained" pattern match. But the compiler doesn't like it.

Giving the compiler a little hint with parentheses helps:

case class ADT(value: Int)

val a = ADT(5)

(a match {
  case ADT(a) if a > 4 => ADT(a * 3)
  case ADT(a) => ADT(a + 1)
}) match {
  case ADT(a) if a > 13 => println(a)
  case _ => {}
}
like image 78
michael.kebe Avatar answered Oct 13 '22 09:10

michael.kebe


Your intuition is correct; it's not nonsense—normally you would be able to chain infix operators in such a way, without parentheses (as other users have suggested). Indeed, match used to be implemented as a method—and worked as an infix operator (left-associative by default)—so your alternate syntax would have worked. However, in Scala 2.5 match was made a special language construct instead of a method. I don't know why that was done, but that's the reason: match is not an infix operator despite seeming so.

like image 32
slackwing Avatar answered Oct 13 '22 09:10

slackwing