mapM /= traverse?

Simon Marlow marlowsd at
Tue May 12 07:58:52 UTC 2015

On 11/05/2015 22:41, Dan Doel wrote:
> The reason I know of why mapM wasn't just made to be an alias for
> traverse (assuming that's what you mean) was that it was thought that
> particular definitions of mapM could be more efficient than traverse.
> For instance:
>      mapM :: Monad m => (a -> m b) -> [a] -> m [b]
>      mapM f = go []
>        where
>        go ys [] = return (reverse ys)
>        go ys (x:xs) = f x >>= \y -> go (y:ys) xs
> This doesn't use stack for m = IO, for instance.
> However, it has since been pointed out (to me and Ed, at least), that
> this matters much less now. Stack overflows are now off by default, and
> if you measure the overall time and memory usage, traverse compares
> favorably to this custom mapM. So, as long as stack isn't an
> artificially scarce resource, there's no reason to keep them distinct.
> We didn't know this until after 7.10, though.
> If you're just asking why the definition of 'mapM' for lists isn't
> 'traverse' with a more specific type, I don't know the answer to that.

Yes, I'm not really concerned that mapM is a method of Traversable 
rather than just being an alias for traverse, but I'm wondering why we 
define it in the list instance rather than using the default.


> -- Dan
> On Mon, May 11, 2015 at 3:15 PM, Simon Marlow <marlowsd at
> <mailto:marlowsd at>> wrote:
>     I was hoping that in GHC 7.10 we would make mapM = traverse for
>     lists, but it appears this isn't the case: the Traversable instance
>     for lists overrides mapM to be the manually-defined version in terms
>     of foldr.
>     Why is this?  Fusion?
>     Unfortunately since I want mapM = traverse (for Haxl) I'll need to
>     continue to redefine it in our custom Prelude.
>     Cheers,
>     Simon
>     _______________________________________________
>     Libraries mailing list
>     Libraries at <mailto:Libraries at>

More information about the Libraries mailing list