Search code examples
scalapattern-matchingpartialfunction

Understand 'case' keyword in partial functions


I am new to Scala and I am trying to decode its constructs, I learned about pattern matching and the syntax is similar to Java switch statement

val x: Int = Random.nextInt(10)

x match {
  case 0 => "zero"
  case 1 => "one"
  case 2 => "two"
  case _ => "other"
}

This code here is pretty obvious and readable. I came across partial functions which are pretty obvious and clear what are they

A partial function is a function that does not provide an answer for every possible input value it can be given.

What I am confused about is using case in the body of a partial function like this:

val divide2: PartialFunction[Int, Int] = {
    case d: Int if d != 0 => 42 / d // WHAT IS THIS ?! 
}

I don't understand how case is used without match statement, how does this is interpreted by Scala, how it is read, is it a method, a class or another construct ?, what other ways I can use case without match statement

Edit:

I tried to play around with this case and still don't get it. For example

val SomeFun: PartialFunction[Int, Int] = {
    case d: Int if d != 0 => 1000 / d
    case f: Int if f != 2 => 100 / f
    case m: Int if m != 1 => 10 / m
  }

How does this work?

Trying this gives an error

val SomeFun = {
    case d: Int if d != 0 => 1000 / d
    case f: Int if f != 2 => 100 / f
    case m: Int if m != 1 => 10 / m
  }


Error:(29, 17) missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?

Is case without match used anywhere else outside a partial function?


Solution

  • I will try to answer this question:

    I don't understand how case is used without match statement, how does this is interpreted by Scala, how it is read, is it a method, a class or another construct ?

    mainly by referring to this article which I will be quoting and paraphrasing.

    The reason this works:

    val f: (Any) => String = {
        case i: Int => "Int"
        case d: Double => "Double"
        case _ => "Other"
    }
    

    is that the compiler interprets it as an anonymous function.

    when you create val function, all you’re really doing with code like this is assigning a variable name to an anonymous function.

    To support that first statement, Section 15.7 of Programming in Scala states:

    A sequence of cases in curly braces can be used anywhere a function literal can be used.

    So it is not really different than using the same syntax inside inside filter or collect.

    The code in the above essentially creates a Function1 object. As this source explains:

    The main distinction between PartialFunction and scala.Function1 is that the user of a PartialFunction may choose to do something different with input that is declared to be outside its domain.