<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Julian Ospald has opened a pull request[*] for containers to add a traversal operation to Data.Set. Julian specifically requested</div><div><br></div><div>    forM :: (Ord b, Monad m) => Set a -> (a -> m b) -> m (Set b)</div><div><br></div><div>Personally, I think it would be better to offer the unflipped versions:</div><div><br></div><div>    -- The most general version</div><div>    traverse :: (Ord b, Applicative f) => (a -> f b) -> Set a -> f (Set b)<br></div><div>    traverse f = fmap fromList . traverse f . toList</div><div><br></div><div>    -- A more efficient, strictly accumulating version for "strict"</div><div>    -- monads like IO, strict State, etc.</div><div>    mapM :: (Ord b, Monad m) => (a -> m b) -> Set a -> m (Set b)</div><div>    mapM f s0 = foldr go return s0 empty<br></div><div>      where</div><div>        go x r s = f x >>= \y -> r $! insert y s</div><div><br></div><div>The latter can also be written, perhaps less efficiently, as</div><div><br></div><div><div>    mapM :: (Ord b, Monad m) => (a -> m b) -> Set a -> m (Set b)</div><div>    mapM f = foldM go empty</div><div>      where</div><div>        go s x = f x >>= \y -> pure $! insert y s</div></div><div><br></div><div>As usual, the main question is what names are appropriate. Typically, containers assumes that users import its modules qualified, and therefore we should just use `traverse` and `mapM`. But clashing with well-known and widely-used names often causes breakage anyway, so I figured I should bring the matter to the libraries list.</div><div><br></div><div>Thanks,</div><div>David Feuer</div><div><br></div><div dir="ltr"><div>[*] <a href="https://github.com/haskell/containers/pull/592">https://github.com/haskell/containers/pull/592</a></div></div></div></div></div></div></div>