Scala сопоставление нескольких типов шаблонов

Мне интересно, как я могу использовать несколько шаблонов шаблонов. У меня есть:

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()
}

Итак, я хотел бы написать что-то вроде:

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

Я видел подобную конструкцию в каком-то учебнике, но это дает мне ошибку:

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

Так есть способ определить несколько разных типов в разделе case? Я думаю, что это сделает код красивее. Как будто у меня будет 5 из них, я буду писать один и тот же код 5 раз (вызов doSomething()).

Спасибо заранее!

Ответ 1

Вам не хватает скобок для классов case. Классы классов без списков параметров устарели.

Попробуйте следующее:

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()
}

Если у вас слишком много параметров для ваших классов case и вам не нравится писать длинные шаблоны Foo(_,_,..), то возможно:

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

Или просто:

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

Но, возможно, вам просто нужны одномерные объекты case?

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()
}