Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Currying and function literals

I was reading the-neophytes-guide-to-scala-part-10 where I came across following code.

type EmailFilter = Email => Boolean

val minimumSize: Int => EmailFilter = n => email => email.text.size >= n

I understood the first line where type alias EmailFilter is created for a function which takes email return boolean. But I don't understand the second line where we take email and number as input and returns boolean by checking size. Please decode the second line and explain me this syntactic sugar code for the function.

like image 847
Kumar Waghmode Avatar asked Dec 01 '22 14:12

Kumar Waghmode


2 Answers

There is no syntactic sugar whatsoever, just raw lambda expressions. If you plug in the type EmailFilter definition into the type in the second line, you obtain

Int => (Email => Boolean)

which is the same (because of right-associativity of =>) as

Int => Email => Boolean 

and this corresponds perfectly with

n   => email => (email.text.size >= n)

which essentially just says: given a number n, create an email filter that, given an email returns true if and only if the length of the email is at least n, so that, for example

minimumSize(100)

returns a closure that behaves just like

email => email.text.size >= 100

i.e. it filters all emails with length greater than or equal 100. Thus, with suitably defined example mails shortMail and longMail, you would obtain:

minimumSize(100)(shortMail) // false
minimumSize(100)(longMail) // true
like image 193
Andrey Tyukin Avatar answered Dec 04 '22 01:12

Andrey Tyukin


The minimumSize function is a curried function.

Currying is a way to split a function call into multiple and sequential subfunction calls.

There are some many good advantages to curry function, one is that it allows your function to be more composable, by deferring the real data source.

Let's depict the usage of:

n => email => email.text.size >= n   

We can first call this function by passing a parameter for n only:

minimumSize(2) // partially applies the minimumSize function with 2 as n 

You will get at this time:

val nextFunction = email => email.text.size >= 2

Next you call nextFunction with an email:

nextFunction(Email("[email protected]"))

You will get at this time a boolean:

val bool = Email("[email protected]").text.size >= 2

So if we sum up:

We started with an Int, then an Email, then a Boolean:

Int => Email => Boolean

And by looking at this signature more carefully, you will recognize the EmailFilter signature.
Let's substitute:

Int => EmailFilter 

The idea is to make the EmailFilter acts as a template, that you can parameterize with some higher functions.
Here we parameterized the email text size comparison so that we can keep the EmailFilter generic.

Keep in mind that functional programming is all about composing functions.

like image 28
Mik378 Avatar answered Dec 04 '22 03:12

Mik378