map package:async

maps an IO-performing function over any Traversable data type, performing all the IO actions concurrently, and returning the original data structure with the arguments replaced by the results. If any of the actions throw an exception, then all other actions are cancelled and the exception is re-thrown. For example, mapConcurrently works with lists:
pages <- mapConcurrently getURL ["url1", "url2", "url3"]
mapConcurrently_ is mapConcurrently with the return value discarded, just like mapM_.