HLint suggests that I use forM_ rather than forM. Why? I see they have different type signatures but haven’t found a good reason to use one over the other.
forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
The
forM_function is more efficient because it does not save the results of the operations. That is all. (This only makes sense when working with monads because a pure function of typea -> ()is not particularly useful.)