Over a million developers have joined DZone.

What in the World Are Applicatives in Scala?

DZone 's Guide to

What in the World Are Applicatives in Scala?

Why do we need Applicatives when we have Functors in Scala? Let's discuss the differences along with an example of implementing Applicatives.

· Big Data Zone ·
Free Resource

In my last article I talked about Functors, now lets talk about Applicatives. Applicatives are also often referred as generalized Functors. In the latter section of the article, we will explore why they are referred to as such.

Before we go into detail, let us discuss a few terms:

  • Pure Functions: as per the Scalaz documentation Pure is defined as an entity that takes a value and puts it in some sort of default (or pure) context—a minimal context that still yields that value.
  • Partially Applied Functions: when applying the function, one does not pass in arguments for all of the parameters defined by the function, but only a few of them, leaving the rest. In return, we get a new function whose parameter list contains only those parameters from the original function that were left blank.
  • arity- n: the arity n of a function or operation is the number of arguments or operands that the function takes.
  • arity -1: a function with a single parameter.
  • arity -2: a function with two parameters.

Now, the vital question is why do we need Applicatives when we have Functors?

As per the definition, Functors are used for lifting computations to a category and they work perfectly for functions with single variable like:

 val incr =(num:Int)=>num+1

But what if we have a function with two or more parameters like the one defined below:

 val sum =(num1:Int)=>(num2:Int)=>num1+num2 

Functors are restricted to lift only functions of arity -1 into computational context. So then we have the problem of how to lift a function of arity -2 into computational context.

Let us see this by above example: Let us invoke fmap to partially apply an arity-2 function(say sum) to its first argument within the computational context of an Option.


The resultant is of type  Option[(Int) => Int], the remaining partially applied function has been wrapped inside Option. Now if we wish to give this to fmap which expects a pure function (not a lifted one) we get STUCK !

Intuitively we need a function to replace fmap taking a pure function, by a method taking a lifted function. Such a method is called apply. The Scalaz documentation defines apply method as a:

  method that takes a function and a functor and applies the function inside the functor value, apply takes a functor that has a function in it and another functor and extracts that function from the first functor and then maps it over the second one.

Also, it defines a method pure which lifts pure functions. The combination of these two makes it feasible to partially apply arity- n function to all of its arguments inside a computational context.

def pure[A](a: A): F[A]

def apply[A, B](f: F[A => B]): F[A] => F[B]

final def apply[A, B](fa: F[A])(f: F[A => B]): F[B] = apply(f)(fa)

override def fmap[A, B](f: A => B): F[A] => F[B] = apply(pure(f))

Every applicative is a functor and by the laws for Applicatives, this property has to hold valid: fmap = apply ο pure. This law ensures that we can use applicative as a functor i.e on arity -1 function.

Applicatives allows us to apply functions of arbitrary arity (>=1) to its arguments inside a computational context, and as functors provide for the exact functions of arity-1, Applicatives can be thought as generalized functors.

Scalaz library has already provided us with the implementation of above code.

Let us look at one of the implementations, Either:

(3.right[String] <**> 4.right[String]) { _ * _ + 10 }

giving us result of type => Either[String,Int] = Right(24)

For more examples and details you can refer to the link or watch the video.

In my next article, I will be talking about Monads. Happy Reading!

functors ,scala ,big data

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}