user3663882 user3663882 - 3 months ago 33
Scala Question

Why is scala match.error thrown?

I'm trying to understand pattern-matching by writing a simple example. Here it is:

def main(args: Array[String]) = {
val tsm = new Test[Number]
tsm.foo(tsm.Val(10))
}

class Test[T <: Any] {
def foo(t: Any): Unit = {
val f: PartialFunction[Any, Unit] = (_: Any) match {
case Val(s) => println("Val" + s)
case Sup(l) => println("Sup" + l)
}
f()
}

class Val(val t: T)
class Sup(val l: Number)

object Val{
def apply(t: T): Val = new Val(t)
def unapply(arg: Val): Option[T] = Some(arg.t)
}
object Sup{
def unapply(arg: Sup): Option[Number] = Some(arg.l)
}
}


But the code throws:

Exception in thread "main" scala.MatchError: () (of class scala.runtime.BoxedUnit)
at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:253)
at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:251)
at com.test.Test$$anonfun$1.applyOrElse(Test.scala:7)
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
at com.test.Test.foo(Test.scala:11)
at com.test.App$.main(App.scala:6)
at com.test.App.main(App.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)


I don't quite understand it. I created an object of type
Val(10)
and passed it into
foo
. I expected it printed
Val10
.

Answer

You define a function f: PartialFunction[Any, Unit] which takes an argument of type Any and then call it f() with no arguments. If you replace f() with f(t) (which is what I think you intended) everything works.