Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should one use applicatives over monads?

I’ve been using Scala at work and to understand Functional Programming more deeply I picked Graham Hutton’s Programming in Haskell (love it :)

In the chapter on Monads I got my first look into the concept of Applicative Functors (AFs)

In my (limited) professional-Scala capacity I’ve never had to use AFs and have always written code that uses Monads. I’m trying to distill the understanding of “when to use AFs” and hence the question. Is this insight correct:

If all your computations are independent and parallelizable (i.e., the result of one doesn’t determine the output of another) your needs would be better served by an AF if the output needs to be piped to a pure function without effects. If however, you have even a single dependency AFs won’t help and you’ll be forced to use Monads. If the output needs to be piped to a function with effects (e.g., returning Maybe) you’ll need Monads.

For example, if you have “monadic” code like so:

val result = for {
 x <- callServiceX(...)
 y <- callServiceY(...) //not dependent on X 
} yield f(x,y)

It’s better to do something like (pseudo-AF syntax for scala where |@| is like a separator between parallel/asynch calls).

val result = (callServiceX(...) |@| callServiceY(...)).f(_,_)

  • If f == pure and callService* are independent AFs will serve you better
  • If f has effects i.e., f(x,y): Option[Response] you’ll need Monads
  • If callServiceX(...), y <- callServiceY(...), callServiceZ(y) i.e., there is even a single dependency in the chain, use Monads.

Is my understanding correct? I know there’s a lot more to AFs/Monads and I believe I understand the advantages of one over the other (for the most part). What I want to know is the decision making process of deciding which one to use in a particular context.

like image 338
PhD Avatar asked Mar 03 '20 01:03

PhD


People also ask

Are all monads Applicatives?

Every Monad is an Applicative Just as IO , every monad can be made into an applicative functor.

Is a monad also a functor?

Generalizing MonadsA monad can be seen as a combination of a functor (we have M[A] with a map that permits us to apply f to each element in M[A] and obtain M[M[B]]) and a monoid (that permits to flatten M[M[B]] into M[B] by means of the associative operator: e.g., concatenation in the case of lists).

What is monad used for?

A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.

What do you know about the functor and monad?

A functor takes a pure function (and a functorial value) whereas a monad takes a Kleisli arrow, i.e. a function that returns a monad (and a monadic value). Hence you can chain two monads and the second monad can depend on the result of the previous one. You cannot do this with functors.


1 Answers

There is not really a decision to be made here: always use the Applicative interface, unless it is too weak.1

It's the essential tension of abstraction strength: more computations can be expressed with Monad; computations expressed with Applicative can be used in more ways.

You seem to be mostly correct about the conditions where you need to use Monad. I'm not sure about this one:

  • If f has effects i.e. f(x,y) : Option[Response] you'll need Monads.

Not necessarily. What is the functor in question here? There is nothing stopping you from creating a F[Option[X]] if F is the applicative. But just as before you won't be able to make further decisions in F depending on whether the Option succeeded or not -- the whole "call tree" of F actions must be knowable without computing any values.


1Readability concerns aside, that is. Monadic code will probably be more approachable to people from traditional backgrounds because of its imperative look.

like image 51
luqui Avatar answered Oct 20 '22 00:10

luqui