Scala functions


#1

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


#2

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

#3

Thanks crater.


#4

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


#5

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.


#6

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

#7

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


#8

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.