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?
monads are used to address the more general problem of computations (involving state, input/output, backtracking, ...) returning values: they do not solve any input/output-problems directly but rather provide an elegant and flexible abstraction of many solutions to related problems.
Monads are not a replacement for applicative functors Instead, every monad is an applicative functor (as well as a functor).
Every Monad is an Applicative Just as IO , every monad can be made into an applicative functor.
As I understand, every monad is a functor but not every functor is a 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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With