Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

More Functions

  • partial applied
  • currying
  • partial functions

Partial Applied Functions

Partial applied mean that not all the parameters are provided. Then the return type is a new function, which can be used with the rest of parameters

scala> val addFunction = (x: Int, y: Int) => x + y
val addFunction: (Int, Int) => Int = Lambda...

scala> addFunction(7, 8)
val res1: Int = 15

scala> val partialAdd1 = addFunction(7, _: Int)
val partialAdd1: Int => Int = Lambda...

scala> partialAdd1(8)
val res2: Int = 15

scala> val partialAdd2 = (x: Int) => addFunction(x, 7)
val partialAdd2: Int => Int = Lambda...

scala> partialAdd2(8)
val res3: Int = 15

scala> def partialAdd3(x: Int) = addFunction(x, 7)
def partialAdd3(x: Int): Int

scala> partialAdd3(8)
val res4: Int = 15

These are partial applied functions Also methods can be partial applied

scala> def addMethod(x: Int, y: Int): Int = x + y
def addMethod(x: Int, y: Int): Int

scala> addMethod(7, 8)
val res5: Int = 15

scala>  val partialAdd4 = addMethod(7, _: Int)
val partialAdd4: Int => Int = Lambda...

scala> partialAdd4(8)
val res6: Int = 15

Currying

scala> def curriedAdd(x: Int)(y: Int) = x + y
def curriedAdd(x: Int)(y: Int): Int

scala> curriedAdd(7)(8)
val res7: Int = 15

scala> val partialAdd5 = curriedAdd(7)
val partialAdd5: Int => Int = Lambda...

scala> partialAdd5(8)
val res8: Int = 15

scala> val partialAdd6 = curriedAdd(7)(_:Int)
val partialAdd6: Int => Int = Lambda...

scala> partialAdd6(8)
val res9: Int = 15

def toCurry(f: (a: Int, b: Int) => Int):  Int => Int => Int =
	x => y => f(x, y)


def fromCurry(f: Int => Int => Int): (Int, Int) => Int =
	(x, y) => f(x)(y)
println(toCurry(_ + _)(2)(3))
println(fromCurry(x => y => x + y)(2, 6))

Function composition

def andThen[A, B, C](f: A => B, g: B => C) =
   (a: A) => g(f(a))

def compose[A, B, C](f: B => C, g: A => B ) =
  (a: A) => f(g(a))

println(compose((z: Int) => z * 2, (y: Int) => y + 10)(3))
println(andThen[Int, Int, Int](z => z * 2, y => y + 10)(3))

Partial Functions

A partial function is a function applicable to a subset of the data it has been defined for.
For example, we could define a function on the Int domain that only works on positive numbers.

val squareRoot: PartialFunction[Double, Double] = 
	def apply(x: Double) = Math.sqrt(x)
	def isDefinedAt(x: Double) = x >= 0

val squareRoot: PartialFunction[Double, Double] = 
  case x if x >= 0 => Math.sqrt(x)

OrElse

val negativeToPositive: PartialFunction[Int, Int] = 
  case x if x <= 0 => Math.abs(x)

val positiveToNegative: PartialFunction[Int, Int] = 
  case x if x > 0 => -1 * x

val swapSign: PartialFunction[Int, Int] = 
	positiveToNegative orElse negativeToPositive

val partialPrint: PartialFunction[Int, Unit] = {
  case x if x > 0 => println(s"$x is greater then zero")
}

(swapSign andThen partialPrint)(-1)

Collect, map and filter

Collect , map and FIlter can be used with partial functions

val parseRange: PartialFunction[Int, Int] = {
  case x: Int if x > 5 => x + 1
}
List(15, 3, "hello") collect { parseRange }
scala> List(1, 2) collect { case i: Int => i > 10 }
val res11: List[Boolean] = List(false, false)

scala> List(1, 2) filter { case i: Int => i > 10 }
val res12: List[Int] = List()

scala> List(1, 2) map { case i: Int if i < 10 => i + 1  }
val res13: List[Int] = List(2, 3)

Here we defined the partial function as an anonymous function.