## Accelerators

### Go to Overview

KDP KDSP

#### TechHub

Akka Scala Rust Spark Functional Java Kafka Flink ML/AI DevOps Data Warehouse

## Insights # Applicatives in Scala

In my last blog we talked about Functors, now lets talk about Applicatives in this Blog. Applicatives are also often referred as generalised Functors. We shall explore in the latter section of the blog why they are referred so.
Before we go into details let us discuss a few terms –

• Pure Functions : as per the Scalaz documentation Pure is defined as 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 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 defination, 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 the problem arises 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.

fmap(Option(20))(sum)

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 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 the 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 exactly functions of arity-1, applicatives can be thought as generalised functors.

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

Let us discuss one of the implementations i.e 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 : link or watch the vedio .  