I'm trying out the code at http://www.scala-lang.org/node/112 and I'm getting a match error for something that doesn't look like it should throw one.
This is the original code:
object Twice {
def apply(x: Int): Int = x * 2
def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None
}
object TwiceTest extends Application {
val x = Twice(21)
x match { case Twice(n) => Console.println(n) } // prints 21
}
I just added a few lines to test what happens when I pass an odd number:
object TwiceTest extends Application {
val x = Twice(21)
x match { case Twice(n) => Console.println(n) } // prints 21
val y = 21
y match { case Twice(n) => Console.println(n) } // throws scala.MatchError: 21 (of class java.lang.Integer)
}
The case for 21 or any odd number should also be handled by the unapply method in the object as far as I can tell. Can someone explain why this is not the case?
val x = Twice(21)
is the same as
val x = Twice.apply(21)
meaning that x
will be equal to 42
. The Twice.unapply(42)
returns a Some(21)
, meaning that the case Twice(21)
successfully matches the value x == 42
.
This is why the first match
statement prints out 21
.
The Twice.unapply(21)
returns None
(because y == 21
, that is, if y
is odd).
Whenever an unapply
returns None
for some value, we say that the extractor object with that unapply
method does not match that value.
If a match
statement does not match a value to any of its cases, it will throw a MatchError
.