Search code examples
haskellmonadsfunctorapplicative

the equivalence between applicative functor and monad


People say monads are an extension of applicative functors, but I don't see that. Let's take an example of applicative functor: (<*>) :: f(a->b) -> f a -> f b

[(+3)] <*> [2,3,4]

Now, I also expect I can do the same thing as monad, it means I can apply 2 parameters: a context contains a function, and another context to get a context. But for monad, I can't. All I need is to write an ugly function like this:

[2,3,4] >>= (\x->[x+3])

Yes, of course, you can say that [(+3)] is equivalent to [\x->(x+3)]. But at least, this function is in context.

Finally, I don't see the equivalence or extension here. Monad is a different style and useful in another story.

Sorry for my ignorance.


Solution

  • If T is an instance of Monad, then you can make it an instance of Applicative like this:

    instance Functor T where
        fmap = liftM
    
    instance Applicative T where
        pure = return
        (<*>) = ap
    

    liftM is defined as

    liftM   :: (Monad m) => (a1 -> r) -> m a1 -> m r
    liftM f m1              = do { x1 <- m1; return (f x1) }
    

    ap is defined as

    ap                :: (Monad m) => m (a -> b) -> m a -> m b
    ap                =  liftM2 id
    
    liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 f m1 m2          = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
    

    So, "monads are an extension of applicative functors" in the sense that any monad can be made into an applicative functor. Indeed, it is widely (not universally) considered a bug in the standard library that class Monad does not derive from class Applicative.