Proposal: Control.Concurrent.Async

Simon Marlow marlowsd at
Sat Jun 9 23:28:23 CEST 2012

On 09/06/12 17:50, Iavor Diatchki wrote:
> Hello,
> A nice library, I've had to re-implement similar functionality, so this
> would be useful!
> Some questions about the waiting combinators:
> 1. I was expecting that `waitAny` and friends, would also return the
> result of the first computation that completed.  Is there a reason not
> to do so?
> 2. Is `waitAny` waiting for one of the Asyncs to complete _successfully_
> or is throwing an exception considered as completion?  I am guessing the
> former, with `waitAnyThrow` providing the latter functionality?
> 3. As far as I understand, `waitAny` does not stop the other asyncs
> (it'd be nice to add this note to its documentation, explicitly).  If
> that's the case, perhaps it's type should be:  `waitAny :: [Async a] ->
> IO (a,[Async a])`, so that we can keep on waiting for more asyncs, if
> needed?

All good points.  I don't have many use cases for the waitAny* family 
yet so I'd been holding off refining the API until I had a clearer 
picture of what would be useful for clients.  There are lots of 
possibilities here.  But in light of your comments I have changed the 
type of waitAny to this:

  waitAny :: [Async a] -> IO (Async a, Either SomeException a)

so that it now returns both the Async that completed and its result. 
Since Async supports Eq, the caller can remove the completed one from 
the list and call waitAny again if necessary.

Similarly waitAnyThrow now has this type:

  waitAnyThrow :: [Async a] -> IO (Async a, a)

I've also added a non-blocking wait:

  tryWait :: Async a -> IO (Maybe (Either SomeException a))

so that after a waitAny the caller can check all of the Asyncs for 
completion and remove multiple completed Asyncs from the list.

Latest Haddocks here:


> -Iavor
> On Fri, Jun 8, 2012 at 1:37 AM, Simon Marlow <marlowsd at
> <mailto:marlowsd at>> wrote:
>     I'd like to add a higher-level concurrency API to the base package.
>     This API has grown while I've been working on examples for my book,
>     and I'm convinced that we should have something like this in the
>     standard libraries.  Here's the API I propose:
>     <>
>     In fact it already exists in at least two packages on Hackage:
>     'async' and 'threads'.  My version is a superset of both of these,
>     except for a few small differences (which are up for discussion, of
>     course).
>     One good reason to have this package is that it avoids some common
>     pitfalls, such as forgetting to handle exceptions in your child
>     threads.  In the Async API, you get to choose whether to (a) receive
>     the result as 'Either SomeException a', or (b) have the exception
>     re-thrown in the waiting thread.  You don't get to ignore it altogether.
>     Another common pitfall avoided by this library is accidentally
>     leaving threads running in the background.  This is handled by
>     withAsync:
>       withAsync :: IO a -> (Async a -> IO b) -> IO b
>     the child thread is always cancelled (i.e. killed) when the second
>     argument returns or throws an exception, if it hasn't finished already.
>     I'm opening this up for discussion so that we can tidy up any
>     inconsistent details and add any functions that people feel are
>     missing.  Naming is obviously up for discussion too.
>     Cheers,
>             Simon
>     _________________________________________________
>     Libraries mailing list
>     Libraries at <mailto:Libraries at>
>     <>

More information about the Libraries mailing list