Partial Functions in Scala
Tags: scala, java, jvm, functional
Published: 2020-08-10 13:09:23

Writing functions and methods that process the input data and produce some output is the very core of any type of programming. When diving deeper into different types of functions in Scala, there is one type that differs from others — partial function. As the element of Scala’s standard library, it is appropriate to know what it is and where it should be used. Let’s dive in!

## What is Partial Function?
>  A partial function of type *PartialFunction[A, B]* is a unary function where the domain does not necessarily include all values of type *A*.
>  *Scala Standard Library*

The definition above, taken straight from the Scala lang standard library docs may seem quite obfuscated. Fear not though, as the concept of partial function is very easy to understand.

In essence, a partial function is a function that accepts only a specific set of data as the input. This doesn’t mean that the function takes only integers and not strings — this behaviour is a standard element of any function. The partial function that accepts integer parameter as the input, can specify what exact integers are accepted.

To better understand the concept, let’s see some code examples.

## How to write Partial Function

First, let’s write a standard function that accepts any input of type Int:
```
   val standardFunction = (x: Int) => x % 10
```
The `standardFunction` is like any other - takes a parameter and returns the remainder when dividing by 10. Now, what if a developer passes zero as the parameter? Or if we need even more refined restrictions regarding the parameter? One way would be to write a long block of ifs and elses, but that is not what you would want to do. Instead, let's write a partial function, like this:
```
    val partialFunction: PartialFunction[Int, Int] = {
        case 1 => 100
        case 2 => 120
        case 3 => 130
      }
```
The `partialFunction` above is defined using the `PartialFunction[Int, Int]` trait. The type parameters say that both input and the output will be of type Int. As you can see, this function accepts only three parameters: either 1, 2 or 3. For any other parameter, an exception will be thrown.

The construction of a partial function is quite easy, but the power comes with the different operators you can use with them. Let’s look at some of them:
```
    partialFunction.isDefinedAt(67)
```
`isDefinedAt()` - this method allows to check if the partial function will accepts a certain parameter - in our case, 67 will not be accepted, and the method will return false.
```
    partialFunction.lift
```
`lift` - this method wraps the return type into an `Option`. For the our `partialFunction`, that will be `Option[Int]`.
```
    partialFunction orElse otherPartialFunction
```
`orElse` - this one is very neat - it allows to chain multiple partial function, if the first one doesn't accept the input, or in different words - it's `isDefinedAt` method returns false.

There is plethora of other methods available — be sure to check out the [official docs](https://www.scala-lang.org/api/current/scala/PartialFunction.html).

## `Map` vs `Collect`

One other interesting behaviour of partial functions can be observed when using it for mapping a collection. Let’s try to use it as if it was a standard function:
```
    List(1, 2, 3, 4, 5).map(partialFunction)
```
The first three parameters are fine — the `partialFunction` have a defined output for them. But what happens with parameters 4 and 5. The answer is: `MatchError`. The map function is not able to determine the output and fails.

The solution to this is to use the collect method. This method uses the `isDefinedAt` method before applying the mapping function, therefore avoiding the `MatchError`.
```
    List(1, 2, 3, 4, 5).collect(partialFunction)
```
## Summary

I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂

{% twitter 1297868840131493889 %}