I have this code:
fmapM :: Monad m => (a -> m b) -> (t, a) -> m (t, b)
fmapM f (id, e) = do
ev <- f e
return (id, ev)
which basically applies the function to the 2nd element in the tuple and then "extracts" the monad. Since the tuple is a functor, is there a way to generalize this for all functors? I cannot think of an implementation, but the type signature should be:
fmapM :: (Monad m, Functor f) => (a -> m b) -> f a -> m f b
it would seem like the 2nd step would be a "sequence" operation, which extracts the monad from another functor (the list). But sequence is not generalized to all functors. Can you come up with a generic implementation of fmapM?
Edit: I've realized that an old version of hugs did have this function implemented. However, I can't find the code. Now, it is suggested that I use foldable/traversable to achieve the same.
The function you're looking for is traverse
, from Data.Traversable
:
traverse :: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
Note that you can't traverse
any Functor
-- for example, (r ->)
-- so there's a separate subclass of Traversable
functors. Also note that you don't need Monad
-- just Applicative
(this generalization is useful).
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