Scala functions

What is partial functions in scala,how to use it?

A partial function is a function, that is only defined for some of its input type’s values. This is implemented by giving the object for a partial function from A to B a method isDefinedAt(a: A): Boolean in addition to the apply method.

You can define a partial function by providing the body in the form of case statements. Here is an example from the documentation:

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

This defines a function, that returns “x is even” for any integer x that is divisible by 2. For any odd integer, isEven.isDefinedAt will return false. If you call isEven with such a value, it will throw a MatchError.

A common use case is the collect method for sequences, which acts like a combined map and filter: the given partial function is applied to all elements in the seq, for which it is defined; if it is undefined for a value, drop that value from the result:

val sample = 1 to 10
val evenNumbers = sample collect isEven
4 Likes

Thanks crater.

Partial function is a function that does not provide an answer for every possible input value it can be given. It provides an answer only for a subset of possible data, and defines the data it can handle. In Scala, a partial function can also be queried to determine if it can handle a particular value.

Regards,
Adrian Gates
Sr. Developer - CloudDesktopOnline

Another common case is to use a partial function where a regular (total) function is expected, in order to rely on the convenient literal syntax:

val list = List(Some(42), None, Some(1))
list.map {
  case Some(n) => n
  case None => 0
}

This is possible because PartialFunction is a subtype of Function.

As a small nitpick, while this is the syntax you can use to create a PartialFunction, the function you are passing into map is not actually a PartialFunction. Function literals using the { case => ... } syntax are only compiled to a PartialFunction when their expected type is PartialFunction.

scala> val f: Function1[Int, Int] = { case 4 => 2 }
f: Int => Int = $$Lambda$3892/89593170@3b4fd4d9

scala> val pf: PartialFunction[Int, Int] = { case 4 => 2 }
pf: PartialFunction[Int,Int] = <function1>

scala> f.isInstanceOf[PartialFunction[_,_]]
res59: Boolean = false

scala> pf.isInstanceOf[PartialFunction[_,_]]
res60: Boolean = true

Interesting. I didn’t know the case syntax could be used for anonymous non-partial functions. Is there a scenario where it matters?

I’m not sure…
There used to be the PartialFunction.apply method which converts normal functions to partial functions. One could be tempted to used it like val pf = PartialFunction[Int, Int]{ case 4 => 2 } and then expect pf.isDefinedAt(7) to be false, which would be a false assumption.