Wednesday, April 24, 2019

Functional Collections - Higher Order Functions

- Higher Order collections takes functions as parameters
   - Methods taking functions as arguments
   - Methods returning a function
- Higher order function provides more abstraction
- Declarative programming (tell what to do, no need on how to do it)

scala> val numbers = Vector(1,2,3)
numbers: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

scala> numbers.map(number=>number+1)
res51: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)

Function Literals
Short notation _stands for one function parameter

scala> numbers.map((number:Int)=>number+1)
res52: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)

scala> numbers.map(number=>number+1)
res53: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)

scala> numbers.map(_+1)
res54: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)


Function Values
Scala has first class functions 

- Function values are objects
- Assign function values to variables
- Pass function values as arguments to higher order functions

scala> val addOne = (n:Int)=>n+1
addOne: Int => Int = <function1>

scala> numbers.map(addOne)
res55: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)


Function Types

If functions are objects, what are their types? REPL shows Int => Int which is syntactic sugar for function1[Int, Int]. All function types define apply method

scala> addOne(7)
res56: Int = 8


Methods and functions

Methods and functions share a lot in common but they are different. If a compiler expects a function but you give a method, method gets lifted to a function

scala> def addOne(n:Int) = n+1
addOne: (n: Int)Int

scala> val addOneFn:Int => Int = addOne
addOneFn: Int => Int = <function1>


Higher Order Function: Map

- Map transforms a collection by applying a function to each element
- Collection type remains but function type may change

scala> val languages = Vector("Scala","Java","Python")
languages: scala.collection.immutable.Vector[String] = Vector(Scala, Java, Python)

scala> languages.map(_.toLowerCase)
res59: scala.collection.immutable.Vector[String] = Vector(scala, java, python)

scala> languages.map(_.length)
res60: scala.collection.immutable.Vector[Int] = Vector(5, 4, 6)


Higher Order Function: FlatMap

- FlatMap transforms a function by applying a function to each element
- Each collection for each element is expanded into a result

scala> Seq("now is", "the time").map(_.split(" "))
res63: Seq[Array[String]] = List(Array(now, is), Array(the, time))

scala> Seq("now is", "the time").flatMap(_.split(" "))
res64: Seq[String] = List(now, is, the, time)

Higher Order Function: Filter

- The predicate is a unary (one argument) function returning a boolean value
- the filter selects elements which satisfies a predicate
- the filterNot selects elements which does not satisfy a predicate


No comments:

Post a Comment