2

I am going trough the https://www.scala-exercises.org/ for Cats. I guess that I understand what does Apply.ap. But I cannot see any usage of that.

What is the difference between:

Apply[Option].map(Some(1))(intToString) 

and

Apply[Option].ap(Some(intToString))(Some(1)) 

Can someone explain a bit more or point me to more explanations ?

4
  • 2
    Being honest, I have never used ap directly. Rather, I have used it implicitly using things like tupled, mapN and traverse. Commented Nov 13, 2020 at 14:36
  • Thanks this was my understanding "not in user code". Luis, there is also apN like mapN, but I guess the answer is the same. Commented Nov 13, 2020 at 14:53
  • 1
    Apply is a specialized type class of Applicative, which is also a Functor. Applicative provides ap operation. It’s very similar to Functor’s map but the function in the argument is already in F[_] domain. In a lot of cases like Monoids they can be used interchangeably with a few exceptions. Commented Nov 13, 2020 at 15:42
  • 1
    In FP ap is more often used as a composition with map of the shape ap(map), which is better known as liftA2. Please note that ap is a very fundamental operation and you should know when to use it instead of flatMap. Commented Nov 13, 2020 at 16:15

1 Answer 1

5

There is no difference between

Apply[Option].map(Some(1))(intToString) 

and

Apply[Option].ap(Some(intToString))(Some(1)) 

Both are Some("1").

But there is a big difference between map and ap.

map comes from the type class Functor and has a signature

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

ap comes from the type class Apply and has a signature

def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] 

So map applies a function A => B to a value in a context F[A] while ap applies a function F[A => B] in a context to a value in a context F[A].

For example

Apply[List].map(List(1, 2))(intToString) 

is List("1", "2") while

Apply[List].ap(List(intToString, (i: Int) => intToString(i) + "a"))(List(1, 2)) 

is List("1", "2", "1a", "2a").

Apply[Option].map(fx)(f) can be None only when fx is None while Apply[Option].ap(ff)(fx) can be None when fx is None or ff is None.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.