PartialFunction in Scala

313 Views Asked by At

I am looking at the PartialFunction source code of Scala. In the file, the trait PartialFunction as well as a companion object PartialFunction are defined. The companion object has methods cond and condOpt.

Link: https://github.com/othiym23/scala/blob/master/src/library/scala/PartialFunction.scala

When I look into andThen as well orElse function, the below method calls are present.

1. PartialFunction.this.isDefinedAt(x)
2. PartialFunction.this.apply(x)

I am not sure from where these functions (isDefinedAt / apply) are present.

Can someone please help where these two methods are present.

Thanks!

2

There are 2 best solutions below

1
On

I guess it's Function1 since PartialFunction extends A => B https://github.com/othiym23/scala/blob/master/src/library/scala/Function1.scala

1
On

apply is defined on Function1, the parent class of PartialFunction (Note that A => B is syntax sugar for Function1[A, B]). isDefinedAt is defined directly on the PartialFunction trait. Note that both are abstract. If you write a function, you're responsible for determining what apply does. If you write a partial function, you're responsible for determining where it's defined.

isDefinedAt will often get magicked away by the compiler if you use partial function syntax. So if we write

val f: PartialFunction[Option[Int], Int] = { case Some(x) => x }

Then we can do

f.isDefinedAt(None) // false
f.isDefinedAt(Some(1)) // true

EDIT: Based on your comment, you're confused by PartialFunction.this.apply. Note the context in which this is executed.

new PartialFunction[A1, B1] {
    def isDefinedAt(x: A1): Boolean = 
      PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
    def apply(x: A1): B1 = 
      if (PartialFunction.this.isDefinedAt(x)) PartialFunction.this.apply(x) 
      else that.apply(x)
  }

We're inside of a new anonymous object. this refers to that anonymous object. If we implemented apply in terms of this.apply, then it would be infinite recursion. Think of PartialFunction.this as being kind of like super, but rather than calling the superclass method, we're calling the concrete class method from inside of an anonymous instance.