# 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 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._

```

```
@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

```

 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)