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)
...
}
While the following “solution” is really just a different way of writing what you already have, it might help if you need to use the same
matchin more than one place and want to avoid code duplication.The following custom unapply:
allows you to write
This way you don’t need to modify the original classes at all. I’m not aware of a better way to do this that doesn’t involve modifying the A/B/C classes, but I’m eager to learn @ Stackoverflow 😉