schmmd
schmmd

Reputation: 19478

Why does this not give a type error?

I would expect this to give me a type error since (String, String) in the else case is not Pair.

case class Pair(x: String, y: String)

val value = Console.readLine.toBoolean

val Pair(x, y) =
  if (value) Pair("foo", "bar")
  else false

Instead, if I enter false, I get the following error at run time.

scala.MatchError: (foo,bar) (of class scala.Tuple2)

I suppose the deconstruction is just sugar for assigning the result to a variable of type Any and then matching on it, but it seems unfortunate that Scala lets this fly.

Upvotes: 10

Views: 151

Answers (1)

drexin
drexin

Reputation: 24403

If you compile this code with scalac -print you see, what happens. As you correctly supposed, it is just syntactic sugar for a pattern matching. Actually your case class extends Product, which also is a superclass of Tuple2 and that is wh your code compiles. Your value gets assigned to a variable of type Product:

val temp6: Product = if (value)
      new Main$Pair("foo", "bar")
    else
      new Tuple2("foo", "bar");

And then a pattern matching is applied to it:

if (temp6.$isInstanceOf[Main$Pair]())
{
  <synthetic> val temp7: Main$Pair = temp6.$asInstanceOf[Main$Pair]();
    new Tuple2(temp7.x(), temp7.y())
}
else
  throw new MatchError(temp6)

But nontheless this shouldn't compile imho. You should post this to the scala mailing list.

Upvotes: 7

Related Questions