Reputation: 5093
The signature of sequence is
sequence :: Monad m => t (m a) -> m (t a)
But we can implement it as
sequence = traverse id
requiring m
to be just Applicative
. If monads are applicatives then why bother having this constraint on type level?
Upvotes: 8
Views: 401
Reputation: 55039
There are many functions in Haskell that are equivalent but distinct because Applicative
(resp. Functor
) didn’t use to be a superclass of Monad
. For example:
return
vs. pure
ap
vs. <*>
liftM
vs. liftA
vs. fmap
liftM2
, liftM3
, &c. vs. liftA2
, liftA3
, &c.
mapM
/forM
vs. traverse
/for
mapM_
/forM_
vs. traverse_
/for_
sequence
vs. sequenceA
mzero
& mplus
(from MonadPlus
) vs. empty
& <|>
(from Alternative
)
The old functions with their original Monad
signatures are still present, but in new code, since the Applicative–Monad Proposal (AMP) was implemented, you can always use the Applicative
versions because they’re slightly more general—that is, you can always replace return
with pure
, but not vice versa.
Upvotes: 8