Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala multiple type pattern matching

I'm wondering how can I use multiple type pattern matching. I have:

abstract class MyAbstract  case class MyFirst extends MyAbstract case class MySecond extends MyAbstract case class MyThird extends MyAbstract // shouldn't be matched and shouldn't call doSomething()  val x: MyAbstract = MyFirst  x match {   case a: MyFirst => doSomething()  case b: MySecond => doSomething()  case _ => doSomethingElse() } 

So I'd like to write something like:

x match {  case a @ (MyFirst | MySecond) => doSomething()  case _ => doSomethingElse() } 

I saw similar construction in some tutorial, but it gives me error:

pattern type is incompatible with expected type; [error]  found   : object MyFirst [error]  required: MyAbstract 

So is there a way to define few different types in on case clause? I think it would make code prettier. As if I will have 5 of them, I will write same code 5 times (calling doSomething()).

Thanks in advance!

like image 288
psisoyev Avatar asked Mar 27 '13 09:03

psisoyev


People also ask

Does Scala have pattern matching?

Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.

What are the different ways to implement match expressions in scala?

Using if expressions in case statements First, another example of how to match ranges of numbers: i match { case a if 0 to 9 contains a => println("0-9 range: " + a) case b if 10 to 19 contains b => println("10-19 range: " + b) case c if 20 to 29 contains c => println("20-29 range: " + c) case _ => println("Hmmm...") }

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.


1 Answers

You are missing the parenthesis for your case classes. Case classes without parameter lists are deprecated.

Try this:

abstract class MyAbstract case class MyFirst() extends MyAbstract case class MySecond() extends MyAbstract  val x: MyAbstract = MyFirst()   x match {    case aOrB @ (MyFirst() | MySecond()) => doSomething(aOrB)    case _ => doSomethingElse() } 

If you have too many params for your case classes and don't like having to write long Foo(_,_,..) patterns, then maybe:

x match {    case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB)    case _ => doSomethingElse() } 

Or just:

x match {    case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB    case _ => doSomethingElse(x) } 

But perhaps you just wanted singleton case objects?

abstract class MyAbstract case object MyFirst extends MyAbstract case object MySecond extends MyAbstract  val x: MyAbstract = MyFirst  x match {    case aOrB @ (MyFirst | MySecond) => doSomething()    case _ => doSomethingElse() } 
like image 178
Faiz Avatar answered Sep 22 '22 17:09

Faiz