Often you have "symmetric" matches and want to write things like:
def g(p:(Int,Int)) = p match {
case (10,n) | (n,10) => println(n)
case _ => println("nope")
}
This is not allowed, but if every alternative has the same variables with the same types, this shouldn't be a problem, as it could be translated to separate cases:
def g(p:(Int,Int)) = p match {
case (10,n) => println(n)
case (n,10) => println(n)
case _ => println("nope")
}
So why do we have this restriction?
Likely because it would take some time to implement and that time is better spent elsewhere. It would also unnecessarily add to the complexity of the language and its compiler. As you already mentioned, the problem can easily be avoided. One other way to avoid the problem is to write a custom extractor:
object ThisOrThat {
def unapply(p:(Int,Int)):Option[Int] = p match {
case (10, n) => Some(n)
case (n, 10) => Some(n)
case _ => None
}
}
It sounds like it would be tedious to implement... There's a feature suggestion from way back.
The obvious workarounds are to either define a function for the result, and call it from separate case
s (better for simple patters), or to define a custom extractor for the alternative pattern, as Kim suggested (better when it is nested inside a pattern you'd rather not have to duplicate).
Either way, it ends up more verbose and harder to read than if it were supported by the language though, so hopefully someone will implement it eventually.