Typeclassopedia presents Traversable:
class (Functor t, Foldable t) => Traversable t where
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
sequenceA :: Applicative f => t (f a) -> f (t a)
mapM :: Monad m => (a -> m b) -> t a -> m (t b)
sequence :: Monad m => t (m a) -> m (t a)
A good exercise is to figure out what the default implementations should be: given either traverse or sequenceA, how would you define the other three methods?
I came up with the following code that type-checks:
class (Functor t, Foldable t) => MyTraversable t where
traverse' :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse' = error "..."
sequenceA' :: Applicative f => t (f a) -> f (t a)
sequenceA' f = traverse' id f
mapM :: Monad m => (a -> m b) -> t a -> m (t b)
mapM = traverse'
sequence' :: Monad m => t (m a) -> m (t a)
sequence' = sequenceA'
If my implementations of mapM and sequence' are correct, and, since every Monad is an Applicative:
λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...
then it's not clear to me why mapM and sequence' are even necessary. Why are they?
P.S. - Credit and my thanks to haoformayor for helping me out with sequenceA.
Monadwas anApplicative. - Daniel Wagner