# What's the difference between Applicatives and Monads?

Lawdefinition (>>=)definition (>=>)definition join / j
left identityreturn a >>= f = f areturn >=> g == gjoin . return == id
right identitym >>= return = mf >=> return == fjoin . fmap pure == id
associativity(m >>= f) >>= g = m >>= (\x -> fx >>= g)f >=> (g >=> h)j . fmap j = j . j

# Applicatives

Lawdefinition
Identitypure id <*> v = v
Homomorphismpure f <*> pure x = pure (f x)
Interchangeu <*> pure y = pure ($y) <*> u Compositionpure (.) <*> u <*> v <*> w = u <*> (v <*> w) # Differences ## What is the difference in Applicatives and Monads? ### High level understanding: key difference is in the second argument. | | Monads (>>=) | Applicatives (<**>) | | full type signature | m a -> (a -> m b) -> m b | f a -> f (a -> b) -> f b | | second argument | a -> m b | f (a -> b) | | difference | First argument, a can decide the future computation m | a is already in the context f | ### Examples for intuition #### Error collecting Monadic instance for Either: instance Monad (Either e) where return = Right v@(Left e) >>= _ = v Right a >>= f = f a  We observe that: Left "Failed 0" >>= \_ -> Left "Failed 1" = Left "Failed 0"  We have lost the information: Left "Failed 1" We might then be tempted to tweak the monad definition, to permit collecting error messages: instance Monoid e => Monad (Either e) where return = Right Left e >>= f = ?? Right a >>= f = f a  What do we want to do? We want to apply f to a value: f a. We can then pattern match on the result: Left e >>= f = case f a of Left e' -> Left (e <> e') Right _ -> Left e  We realize that we can’t do that however. Left e is part of the context and does not return any result, in contrast to Right a. Since f only takes in a as a functional dependency (since f :: a -> m b) The context of the computation (f a in f a -> (a -> m b)) is opaque to it. As such we can only do 2 things: 1. If we can get a result, pass it into f. 2. If we can’t get a result, short circuit, since we can’t evaluate f in any way. Wait a minute, you say. What if we did this: Left e >>= \_ -> Left e' = Left (e <> e')  We can’t do that either because we cannot go into function bodies! We can only see the mapping between input and the result. What about this then! Left e >> Left e = Left (e <> e')  Yes we could do that. Note however, this is not powerful enough to give us a monad. We are unable to define (>>=) in terms of (>>) (although the vice-versa works). (Possible) Applicative instance for Either: instance Monoid e => Applicative (Either e) where pure = Right Left e <*> Left e' = Left (e <> e') Left e <*> Right a = Right a Right f <*> Left e' = Left e' Right f <*> Right a = Right$ f a


This is because Applicative interface separate the context layer (f (a -> b)) rather than (a -> f b).

This makes the (<*>) operator able to work on the contexts as well.

#### Further examination of applicative patterns

Let’s examine two types of computations:

Here, we can see that p1, p2 are not dependent on previous result. The final result uses return which means it does not introduce any new context.

do val1 <- p1
val2 <- p2
return \$ f val1 val2


We can thus represent this in applicative form:

pure f <*> val1 <*> val2


Here we can see a dependence:

do val1 <- p1
val2 <- p2 val1 -- p2 is dependent on the result of p1
return val2