Partial Functions

A partial function is a trait that when implemented can be used as building blocks to determine a solution. The trait PartialFunction requires that the method isDefinedAt and apply be implemented:

val doubleEvens: PartialFunction[Int, Int] =
  new PartialFunction[Int, Int] {
    //States that this partial function will take on the task
    def isDefinedAt(x: Int) = x % 2 == 0

    //What we do if this partial function matches
    def apply(v1: Int) = v1 * 2
  }

val tripleOdds: PartialFunction[Int, Int] = new PartialFunction[Int, Int] {
  def isDefinedAt(x: Int) = x % 2 != 0

  def apply(v1: Int) = v1 * 3
}

val whatToDo = doubleEvens orElse tripleOdds //Here we chain the partial functions together

whatToDo(3) should be(res0)
whatToDo(4) should be(res1)

Case statements are a quick way to create partial functions. When you create a case statement, the apply and isDefinedAt methods are created automatically.

val doubleEvens: PartialFunction[Int, Int] = {
  case x if (x % 2) == 0 => x * 2
}
val tripleOdds: PartialFunction[Int, Int] = {
  case x if (x % 2) != 0 => x * 3
}

val whatToDo = doubleEvens orElse tripleOdds //Here we chain the partial functions together
whatToDo(3) should be(res0)
whatToDo(4) should be(res1)

The result of partial functions can have an andThen function added to the end of the chain:

val doubleEvens: PartialFunction[Int, Int] = {
  case x if (x % 2) == 0 => x * 2
}
val tripleOdds: PartialFunction[Int, Int] = {
  case x if (x % 2) != 0 => x * 3
}

val addFive = (x: Int) => x + 5
val whatToDo =
  doubleEvens orElse tripleOdds andThen addFive //Here we chain the partial functions together
whatToDo(3) should be(res0)
whatToDo(4) should be(res1)

andThen can be used to continue onto another chain of logic:

val doubleEvens: PartialFunction[Int, Int] = {
  case x if (x % 2) == 0 => x * 2
}
val tripleOdds: PartialFunction[Int, Int] = {
  case x if (x % 2) != 0 => x * 3
}

val printEven: PartialFunction[Int, String] = {
  case x if (x % 2) == 0 => "Even"
}
val printOdd: PartialFunction[Int, String] = {
  case x if (x % 2) != 0 => "Odd"
}

val whatToDo = doubleEvens orElse tripleOdds andThen (printEven orElse printOdd)

whatToDo(3) should be(res0)
whatToDo(4) should be(res1)