val f: PartialFunction[Int, Int] =
new PartialFunction[Int, Int] {
override def apply(x: Int): Int =
x match {
case 1 => 100
case 2 => 200
case _ if x != 0 => 300
}
override def isDefinedAt(x: Int): Int =
x match {
case 1 => true
case 2 => true
case _ if x != 0 => true
case _ => false
}
Just so. Keep in mind that the fully-spelled-out version is generated by the compiler; it is quite rare to bother doing so by hand. (Legal, and there are probably edge cases where it is appropriate, but I’m not sure I’ve done so in a dozen years of writing Scala.)
What you really get is applyOrElse, which is what apply uses:
➜ ~ scala -Vprint:typer
Welcome to Scala 2.13.8 (OpenJDK 64-Bit Server VM, Java 17.0.1).
Type in expressions for evaluation. Or try :help.
scala> val f: PartialFunction[Int, Int] = {
| case x: Int if x != 0 => 100
| }
[[syntax trees at end of typer]] // <console>
private[this] val f: PartialFunction[Int,Int] = ({
@SerialVersionUID(value = 0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[Int,Int] with java.io.Serializable {
def <init>(): <$anon: Int => Int> = {
$anonfun.super.<init>();
()
};
final override def applyOrElse[A1 <: Int, B1 >: Int](x1: A1, default: A1 => B1): B1 = ((x1.asInstanceOf[Int]: Int): Int @unchecked) match {
case (x @ (_: Int)) if x.!=(0) => 100
case (defaultCase$ @ _) => default.apply(x1)
};
final def isDefinedAt(x1: Int): Boolean = ((x1.asInstanceOf[Int]: Int): Int @unchecked) match {
case (x @ (_: Int)) if x.!=(0) => true
case (defaultCase$ @ _) => false
}
};
new $anonfun()
}: PartialFunction[Int,Int]);
The purpose is to avoid double-evaluation of the pattern match:
if (pf.isDefinedAt(x)) pf.apply(x)
Here is the definition of PartialFunction.cond, which conceptually “supplies a default case” for a boolean test:
wow… thx for your reply… this is mind-blowing… some questions in return…
where to find more info about scala command line flags? I would like to understand what ‘-Vprint:typer’ means and what else is possible…
why is the generated version of PartialFunction lacking the apply method? My best guess; the trait does not contain a method ‘apply’ because in some magical way the ‘apply’ method I stated in my code gets converted by the compiler?
For command options there is a page, though I normally just cargo cult or use the command line scalac -help and -X etc. I haven’t checked what scala-cli does yet, though I know Scala 3 doesn’t have all the bells and whistles, but an overlapping set.