Working with Functions in Scala – Part 2

In this part, we take functions a little further and discuss the following:

  1. Working with Lists of Functions
  2. Generated Functions

This builds a bit on the previous post on Functions in Scala, so if you haven’t seen it already, I’d highly suggest you take a look here: Working with Functions in Scala – Part 1

Working with Lists of Functions

Having come this far, the natural reaction would be to see if we can create a List of functions and have them apply either individually or as a composite function. Let’s see how this can be done in Scala.

A List of functions can be defined as follows:

val f = (x: Int) => x + 2
val g = (x: Int) => x * 2
val h = (x: Int) => x – 2

We can create a List of these functions as follows:

val funcList = List(f,g,h)

If you enter this in the console or the worksheet, you would see the result as follows:

funcList : List[Int => Int] = List(<function1>, <function1>, <function1>)

Notice that Scala automatically and correctly identifies the List type as [Int=>Int]. You could make this explicit also as follows:

val funcList = List[Int=>Int](f,g,h)

Let’s see how to apply each function individually to a value. We can refer to each function by the index value as follows:

funcList(0) //This is f

funcList(1) //This is g

funcList(2) //This is h

So, if we want to apply all functions to generate a list of values, we can do that using the map function:

funcList map (t=>t(3)) //> res1: List[Int] = List(5, 6, 1)

Or we can define this operation as another function as follows:

val doFunc = (x: Int) => funcList map (t => t(x))

Having read a lot of posts online about Scala, I can understand that something like the statement above can get quite confusing. So do take some time to understand it. The definition is similar to the way we define f, g and h

Once we define it like this, we can get the list as follows:

doFunc(3) //> res1: List[Int] = List(5, 6, 1)

Now let’s get to something more interesting. Suppose we have the list of functions f, g and h as earlier and we want to progressively feed in the result from each function as the argument to the next. This just begs to be tackled using reduce or fold and we’ll see how to do it with both. Mathematically, we’re about to calculate:

h o g o f (x)

Let’s name the composite function as compFunc. The function reduceLeft requires an operator that will work on the function. The operator we will use is andThen. The composite function can then be obtained as:

val compFunc = funcList.reduceLeft(_ andThen _)

To be honest, the underscore (_) character is sometimes more trouble than it’s worth. Here’s the same definition without the underscore, it should make things clearer:

val compFunc = funcList.reduceLeft((acc, item)=> acc andThen item)

Here, acc stands for accumulator and item refers to the current item it’s iterating over. If this is still confusing, I would suggest reading up on the reduceLeft method.

Now, we can evaluate compFunc with a variable as follows and we can see that we get the correct answer 8

compFunc(3) //> res10: Int = 8

We can do the same thing using the foldLeft method. But since the foldLeft requires an initial value, we need to give it an initial function. To ensure the value is what we expect it to be, we need to give it an identity function like so:

val identity = (x:Int)=>x

So, using this, we can now do the same thing with foldLeft as follows:

val compFunc2 = funcList.foldLeft(identity)((acc,item)=>acc andThen item)

And it gives the correct answer as expected:

compFunc2(3) //> res11: Int = 8

Generated Functions

This is very fine and useful, but obviously this leads to another powerful feature of Scala that beats regular Java. Dynamically generated functions or functions generated at runtime.

We will consider an overly simplified case here, but no reason why it can’t be expanded to other more complicated functions as well. Let’s say that you require a function that will change it’s behaviour according to user input.

We’ll generate a list of functions that vary from a ‘start’ value to a ‘finish’ value as follows:

x+start

x+(start+1)

x+(start+2)

x+(finish-1)

x+(finish)

Let’s assume you got the variables start and finish from the user. For the purpose of this write-up, we’ll just use declared variables:

val start = 3

val finish = 8

The function list can be generated as follows:

val fList = (start to finish) map (t=> (x:Int)=>x+t)

 

And this concludes this 2 part write-up on Scala Functions. I hope you’ve found these posts helpful. Of course Scala is huge and there are a myriad of ways to solve any single problem. Functions are one of the big reasons to use Functional Programming languages such as Scala and it helps to be able to know them well.

Advertisements

One thought on “Working with Functions in Scala – Part 2

  1. Pingback: Working with Functions in Scala – Part 1 « Emptiness in void

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s