November 26, 2019
by Niranjan Tallapalli

**Higher Order Functions** This takes functions as input parameters and return another function as an output aka HOFs

Note: map, flatMap, filter belongs to HOFs as they take function as an arg

Example

val superFunction: (Int, (String, (Int => Boolean)) => Int) => (Int => Int) = null
// Input: (String, (Int => Boolean)) => Int) // function within a function
// Output: (Int => Int) // another function which takes Int and returns Int

**Currying Functions**

Function that applies a given function ‘n’ times over a given value ‘x’

// nTimes(F, n, x)
// nTimes(f, 3, x) = f(f(f(x))) = nTimes(f, 2, f(x))
def nTimes(f: (Int => Int), n: Int, x: Int): Int = {
if (n == 0) x
else nTimes(f, n-1, f(x))
}
val adder: Int => Int = _ + 1
val result = nTimes(adder, 10, 0)
println(result)
// better way of writing it is to return a function that can compute the value
// ntb(f, n) = x => f(f(f(....(x))))
def nTimesBetter(f: Int => Int, n: Int): Int => Int = {
if (n == 0) (x: Int) => x
else (x: Int) => nTimesBetter(f, n-1)(f(x))
}
val plus10 = nTimesBetter(adder, 10)
println(plus10(0))

Examples on how to consume and return curried functions

def toCurry(f: (Int, Int) => Int): (Int => Int => Int) =
x => y => f(x, y) // lambda taking value 'x', returns a lambda taking value 'y' and the result is f(x, y)
// It receives a function of type (Int, Int) => Int
// It returns a curried function
// Note: Looks simple to read but its very hard to think about
def fromCurry(f: Int => Int => Int): (Int, Int) => Int =
(x, y) => f(x)(y)
// TEST
// def superAdder2: (Int => Int => Int) = toCurry(_ + _) is same as below one
def superAdder2: (Int => Int => Int) = toCurry((x, y) => x + y)
def add4 = superAdder2(20)
println(add4(7))

Scala supports another kind of curried function by specifying functions with **MULTIPLE PARAMETER LISTS**

Curried Formats are like PARTIAL FUNCTIONS in JS

Note: For functions with multiple parameters, if we want to define smaller functions later (Line:43) we have to define type on RHS, otherwise it will not compile.

def curriedFormatter(stringFormat: String)(value: Double): String = stringFormat.format(value)
val standardFormat: (Double => String) = curriedFormatter("%4.2f")
val preciseFormat: (Double => String) = curriedFormatter("%10.8f")
println(standardFormat(Math.PI))
println(preciseFormat(Math.PI))

Function Library (Function1 till Function22) has two very important functions that are very useful.

// genericize the above two functions
def compose[A, B, T](f: A => B, g: T => A): T => B = x => f(g(x))
def fromThen[A, B, C](f: A => B, g: B => C): A => C = x => g(f(x))
val add2 = (x: Int) => x + 2
val times3 = (x: Int) => x * 3
val composed = compose(add2, times3)
println(composed(4)) // T=4, A=12, B=14 result is 14
val ordered = fromThen(add2, times3)
println(ordered(4)) // A=4, B=6, C=18 result is 18

## Recent Comments