multiset
multiset copied to clipboard
Convenience function mapM
As a user, I would like the monad version of map to be provided by the multiset library instead of having to define it locally each time I need it. Consequently, when a better implementation is possible, I don't have to change my code in many places.
MultiSet already offers the map function of signature Ord b => (a-> b) -> MultiSet.MultiSet a -> MultiSet.MultiSet b
.
Could you also offer something like
{-# LANGUAGE ScopedTypeVariables #-}
mapM :: forall a b m . (Ord b, Monad m) => (a-> m b) -> MultiSet.MultiSet a -> m (MultiSet.MultiSet b)
mapM f a = MultiSet.fromOccurList <$> mapM f' (MultiSet.toOccurList a)
where f' :: (a, MultiSet.Occur) -> m (b, MultiSet.Occur)
f' (x,c) = do
v <- f x
return (v,c)
I use the naming convention: A postfix 'M' always stands for a function in the Kleisli category: The monad type constructor m is added to function results (modulo currying) and nowhere else. So, for example,
filter :: (a -> Bool) -> [a] -> [a]
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
It makes sense to add mapM
. Especially because it exists for Map
and Set
from containers.
Note that Data.Set
in fact doesn't offer a mapM
function, probably because mapM
is usually defined in terms of a Traversable
instance, which Set
doesn't have – it isn't even a Functor
.