Higher Order Functions (HOFs) and Currying In Scala

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.

  • compose
  • fromThen
    // 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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Mawazo

Mostly technology with occasional sprinkling of other random thoughts

amintabar

Amir Amintabar's personal page

101 Books

Reading my way through Time Magazine's 100 Greatest Novels since 1923 (plus Ulysses)

Seek, Plunnge and more...

My words, my world...

ARRM Foundation

Do not wait for leaders; do it alone, person to person - Mother Teresa

Executive Management

An unexamined life is not worth living – Socrates

Diabolical or Smart

Nitwit, Blubber, Oddment, Tweak !!

javaproffesionals

A topnotch WordPress.com site

thehandwritinganalyst

Just another WordPress.com site

coding algorithms

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem." -- John Tukey