9

In this set of slides by Jim Duey at slide 13 - he suggests that all Monads are applicative functors.

enter image description here

In the Haskell 7.7 compiler output - I'm seeing the following (another example is here):

‛Parser’ is an instance of Monad but not Applicative - this will become an error in GHC 7.10, under the Applicative-Monad Proposal.

Does this mean the Haskell Compiler currently tolerates Monads that are not applicative functors - but the plan is to correct this?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
hawkeye
  • 34,745
  • 30
  • 150
  • 304
  • 2
    All `Monad`s *can be made* an instance of `Applicative`, but not all of them necessarily have been (at least not by GHC 7.6). – Tom Ellis Nov 17 '13 at 14:23

1 Answers1

11

Right now Applicative isn't a superclass of Monad

instance Monad m where ...      -- this is how it is today, instead of
instance Applicative m => Monad m where ...

but it is planned so that in GHC 7.10 this will be changed so that Applicative is a superclass of Monad. In order to help the transition, in GHC 7.7 and 7.8 there will be the warning you saw issued whenever GHC encounters a Monad without an Applicative instance.


Now the slightly confusing bit is that all valid Monads are applicative functors, even if they're not instances of Applicative. We can write

fmapM :: Monad m => (a -> b) -> m a -> m b
fmapM f ma = ma >>= return . f                      -- a.k.a. `liftM`

pureM :: Monad m => a -> m a
pureM = return

ap :: Monad m => m (a -> b) -> m a -> m b
ap mf ma = do { f <- mf; a <- ma; return (f a) }    -- a.k.a. `ap`

which together satisfy the signature and laws of Functor and Applicative. This is why the superclass constraint makes sense to add and it's purely historical accident that it wasn't there in the first case—Applicatives were discovered and popularized far after Monads were.

newtype WrappedMonad m a = WM (m a)

instance Monad m => Functor (WrappedMonad m) where
  fmap f (WM m) = WM (liftM f m)

instance Monad m => Applicative (WrappedMonad m) where
  pure = WM . return
  WM mf <*> WM ma = WM $ mf `ap` ma

For more information on how Applicative and Monad relate, take a look at an answer I wrote previously here: Is it better to define Functor in terms of Applicative in terms of Monad, or vice versa?

Community
  • 1
  • 1
J. Abrahamson
  • 72,246
  • 9
  • 135
  • 180
  • 3
    Another way to say this might be: "all monads are applicative functors (mathematically speaking), but not all `Monad`s are `Applicative`s (Haskellically speaking and in GHC ≤7.8)." – Antal Spector-Zabusky Nov 17 '13 at 11:42
  • 1
    What will change in the code? Does it mean that for each monad we will have to add the definitions of `fmap`, `pure`, `<*>` or will they be added somehow automatically, since for a monad they always have the same definition in terms of `return` and `>>=`? – Giorgio Dec 19 '14 at 17:00
  • 1
    We'll have `class Applicative m => Monad m` so that in order to declare `instance Monad m` you must first declare `instance Applicative m`. For most monads the applicative instance can be cheaply instantiated as `instance Applicative m where { pure = return; (<*>) = ap }`. – J. Abrahamson Dec 19 '14 at 17:10