Functions are first class citizens in Scala. ‘sum’ function takes two integer arguments and return the sum of two variables.
scala> def sum(a: Int, b : Int) = a + b
def sum(a: Int, b: Int): Int
scala> sum(10, 20)
val res2: Int = 30
you can store a function in a variable.
def sum(a: Int, b : Int) = a + b
Let’s store the function ‘sum’ into a variable ‘add’.
def add = sum(_, _)
scala> def sum(a: Int, b : Int) = a + b
def sum(a: Int, b: Int): Int
scala> def add = sum(_, _)
def add: (Int, Int) => Int
scala> sum (10, 20)
val res4: Int = 30
scala> add(10, 20)
val res5: Int = 30
You can even use below shorthand notation to store a function into a variable.
def add = sum _
scala> def add = sum _
def add: (Int, Int) => Int
scala> add(10, 20)
val res6: Int = 30
Higher Order function
You can pass function as an argument to other function or method.
def square(x : Int) = x * x
I can pass square function as an argument to map function, which apply ‘square’ function to every elements of the collection.
Array(2, 3, 5, 7).map(square)
scala> def square(x : Int) = x * x
def square(x: Int): Int
scala> Array(2, 3, 5, 7).map(square)
val res0: Array[Int] = Array(4, 9, 25, 49)
If you do not want to define new function square, you can pass a lambda expression to map function.
scala> Array(2, 3, 5, 7).map(ele => ele * 2)
val res1: Array[Int] = Array(4, 6, 10, 14)
You can use filter function to filter the elements from a collection.
For example, filter all the elements that are divisible by 5.
1.to(100).filter(_ % 5 ==0)
scala> 1.to(100).filter(_ % 5 ==0)
val res17: IndexedSeq[Int] = Vector(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100)
Define Custom Higher order function
Let’s define a higher order function apply that takes an array of integers and a function as input and apply this function to every element of the array.
Example
def apply(elements: Array[Int], fun: (Int) => Int) : Array[Int] = for (ele <- elements) yield fun(ele)
As you see the definition of apply function, second argument is a function that takes one integer as argument and return an integer.
Let’s double each element in the array.
scala> def apply(elements: Array[Int], fun: (Int) => Int) : Array[Int] = for (ele <- elements) yield fun(ele)
def apply(elements: Array[Int], fun: Int => Int): Array[Int]
scala> def square(x : Int) = x * x
def square(x: Int): Int
scala> apply(Array(2, 3, 5, 7), square)
val res3: Array[Int] = Array(4, 9, 25, 49)
Let’s triple each element in the array.
scala> def cubes(x: Int) = x * x * x
def cubes(x: Int): Int
scala> apply(Array(2, 3, 5, 7), cubes)
val res4: Array[Int] = Array(8, 27, 125, 343)
Function can produce other functions
A function can produce other functions.
Example
def incBy(factor: Int) = (number: Int) => factor + number
I can define incBy1 and incBy5 functions using incBy function.
val incBy1 = incBy(1)
val incBy5 = incBy(5)
You can call incBy1 and incBy5 functions like below.
incBy1(10)
incBy5(10)
scala> def incBy(factor: Int) = (number: Int) => factor + number
def incBy(factor: Int): Int => Int
scala> val incBy1 = incBy(1)
val incBy1: Int => Int = $Lambda$1045/37858242@7e5e7753
scala> incBy1(10)
val res5: Int = 11
scala> incBy1(21)
val res6: Int = 22
scala>
scala> val incBy5 = incBy(5)
val incBy5: Int => Int = $Lambda$1045/37858242@3284f91f
scala> incBy5(10)
val res7: Int = 15
scala> incBy5(21)
val res8: Int = 26
No comments:
Post a Comment