How exactly "case" works in partial functions in Scala?

Alex N. picture Alex N. · Nov 24, 2013 · Viewed 8.3k times · Source

I am just starting my seemingly steep learning curve with Scala and can't quite grasp how "case" works in partial functions exactly.

I looked at the definition of PartialFunction itself, and there I see a sample like the following:

val isEven: PartialFunction[Int, String] = { 
   case x if x % 2 == 0 => x+" is even" 
}

The part where I am getting stuck is case x if x%2 -- how does Scala know what's what here? What is a formal definition of this "case" statement/keyword?

I think one reason for my confusion is because in Lift I see things like the following(in Actor classes):

override def messageHandler = {
   case SomeKindOfUserMessageClass(id1, param1) => ....
   case AnotherKindOfUserMessageClass(id2) => ....
}

I sort of understand intuitively what's going on here, but I can't assemble some kind of unified definition of how "case" should be used. Even more puzzling to me is how Scala compiler untangles all that.

Answer

Chris Martin picture Chris Martin · Nov 24, 2013

The thing you're asking about is called pattern matching. A pattern match block can be used with the match keyword, or it can be used to define either a function or a partial function, depending on the context.

Your second example uses extractors. Scala's evaluation of m match { case A(x) => } involves calling A.unapply(m). The companion object of a case class is an extractor (using case classes is more common than actually writing an unapply method).

The Scala Language Specification is a tough read, but sometimes it's worth trying to take a look at, especially if you're looking for formalism. Chapter 8 is about pattern matching. Section 8.4 introduces the idea of using if in a case clause like in your first example.