Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are variables not allowed in alternative patterns?

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?

like image 509
Landei Avatar asked Jul 03 '11 08:07

Landei


2 Answers

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
  }
}
like image 126
Kim Stebel Avatar answered Oct 20 '22 14:10

Kim Stebel


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 cases (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.

like image 39
aij Avatar answered Oct 20 '22 15:10

aij