Scala multiple type pattern matching

65,304

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()
}
Share:
65,304
psisoyev
Author by

psisoyev

Scala enthusiast

Updated on July 08, 2022

Comments

  • psisoyev
    psisoyev almost 2 years

    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!

  • psisoyev
    psisoyev about 11 years
    And there is no way to avoid parenthesis? As I have a few parameters and it becomes ugly: case a @ (MyFirst(, _, _, _, _) | MySecond(, _, _, _, _)) => doSomething()
  • Jean-Philippe Pellet
    Jean-Philippe Pellet about 11 years
    Did you miss obj @ (_: MyFirst | _: MySecond)?
  • psisoyev
    psisoyev about 11 years
    I need obj in cases, where I'm using it in doSomething call. In my case, the call of doSomething wasn't using obj, so I don't need it. But anyway, thanks for your comment!
  • Faiz
    Faiz about 11 years
    @Jean-PhilippePellet Indeed I have. Let me edit my post to add it.
  • Kevin Meredith
    Kevin Meredith about 10 years
    What am I doing wrong here - scala> def foo(a: Any) = a match { | case x @ (Int) => x | } foo: (a: Any)Int.type scala> val a = 100 a: Int = 100 scala> foo(a) scala.MatchError: 100 (of class java.lang.Integer) at .foo(<console>:8)?
  • nilskp
    nilskp over 9 years
    It would be nice if the compile was smart enough to find the closest common type instead of defaulting to the input type.