I have a case class like the following:

// parent class
sealed abstract class Exp()

// the case classes I want to match have compatible constructors
case class A (a : Exp, b : Exp) extends Exp
case class B (a : Exp, b : Exp) extends Exp
case class C (a : Exp, b : Exp) extends Exp

// there are other case classes extending Exp that have incompatible constructor, e.g.
//     case class D (a : Exp) extends Exp
//     case class E () extends Exp
// I don't want to match them

I want to match:

var n : Exp = ...
n match {
    ...
    case e @ A (a, b) => 
        foo(e, a)
        foo(e, b)
    case e @ B (a, b) => 
        foo(e, a)
        foo(e, b)
    case e @ C (a, b) => 
        foo(e, a)
        foo(e, b)
    ...
}

def foo(e : Exp, abc : Exp) { ... }

is there a way to merge that three cases into a single case (without adding an intermediate parent class to A,B,C)? I can't change the definition of A, B, C, or Exp. Some sort of:

var n : Exp = ...
n match {
    ...
    case e @ (A | B | C) (a, b) => // invalid syntax
        foo(e, a)
        foo(e, b)
    ...
}

which obviously does not work, and neither do:

var n : Exp = ...
n match {
    ...
    case e @ (A (a, b) | B (a, b) | C (a, b)) => // type error
        foo(e, a)
        foo(e, b)
    ...
}
Edit
Report