## Applicative in Scala Cats

I always heard about Applicative, but I don’t know what really is. So, I write this post to understand myself. Below picture is from adit.io and example is from mastering advanced Scala.

What is Applicative?

During programming, you will encounter this situation.

```def getSome(a: Int): Option[Int] = Some(a)

def getNone(a: Int): Option[Int] = None

def add(a: Int, b: Int): Int = a + b

val aOpt = getSome(1)

val bOpt = getSome(2)

```

And I want to get aOpt and bOpt add together using add. But aOpt and bOpt is Option. So, the usual way to do is by using flatMap and map like this.

```
aOpt.flatMap(a => bOpt.map(b => add(a, b)))
// res0: Option[Int] = Some(3)

```

In here, we can use Applicative.

What is Applicative?

I don’t know that my understanding of Applicative is right. But I think, Applicative is

Very famous picture about Applicative.

In here there is a wrapped value: 2. And there is a wrapped function. We unwrapped both function and value, and process some operation and wrap it again! And we can also adapt these things to above example.

```
import cats.instances.option._
import cats.Applicative

// res1: Option[Int] = Some(3)

```

We can also use like this.

```
import cats.syntax.all._

```

### Monad extends Applicative

```
@typeclass trait Monad[F[_]] extends FlatMap[F] with Applicative[F] {
override def map[A, B](fa: F[A])(f: A => B): F[B] =
flatMap(fa)(a => pure(f(a)))
}

```

As you can see, Monad extends Applicative. And Applicative extends Functor. So, hierarchy is ‘Monad <: Applicative <: Functor’

### Tip – Traverse

While studying with Mastering Advanced Scala, there are some tips in Applicative, So, I write down this. If there is a List[Int] and want all element adapt ‘getSome’ function, for example

```
val ints = List(1,2,3,4,5)
ints.map(getSome)
// res3: List[Option[Int]] = List(Some(1), Some(2), Some(3), Some(4), Some(5))
```

The result is ‘List(Some(1), Some(2), Some(3), Some(4), Some(5))’ and if you want to make ‘Some(List(1, 2, 3, 4, 5))’ you can use Traverse like this.

```
import cats.Traverse
import cats.instances.list._
import cats.instances.option._

Traverse[List].traverse(ints)(getSome)

// res4: Option[List[Int]] = Some(List(1, 2, 3, 4, 5))

```

This will return None if any element return None

```
def getSomeOrNone(a: Int): Option[Int] =
if(a % 2 == 0) Some(a)
else None

Traverse[List].traverse(ints)(getSomeOrNone)

// res5: Option[List[Int]] = None

```

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 def getSome(a: Int): Option[Int] = Some(a) def getNone(a: Int): Option[Int] = None def add(a: Int, b: Int): Int = a + b val aOpt = getSome(1) val bOpt = getSome(2) aOpt.flatMap(a => bOpt.map(b => add(a, b))) import cats.instances.option._ import cats.Applicative Applicative[Option].map2(aOpt, bOpt)(add) import cats.syntax.all._ (aOpt |@| bOpt).map(add) val ints = List(1,2,3,4,5) ints.map(getSome) import cats.Traverse import cats.instances.list._ import cats.instances.option._ Traverse[List].traverse(ints)(getSome) def getSomeOrNone(a: Int): Option[Int] = if(a % 2 == 0) Some(a) else None Traverse[List].traverse(ints)(getSomeOrNone)