-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | This package provides a higher-level interface over threads, in which
--   an <tt>Async a</tt> is a concurrent thread that will eventually
--   deliver a value of type <tt>a</tt>. The package provides ways to
--   create <tt>Async</tt> computations, wait for their results, and cancel
--   them.
--   
--   Using <tt>Async</tt> is safer than using threads in two ways:
--   
--   <ul>
--   <li>When waiting for a thread to return a result, if the thread dies
--   with an exception then the caller must either re-throw the exception
--   (<a>wait</a>) or handle it (<a>waitCatch</a>); the exception cannot be
--   ignored.</li>
--   <li>The API makes it possible to build a tree of threads that are
--   automatically killed when their parent dies (see
--   <a>withAsync</a>).</li>
--   </ul>
@package async
@version 2.2.5


-- | This module is an internal module. The public API is provided in
--   <a>Control.Concurrent.Async</a>. Breaking changes to this module will
--   not be reflected in a major bump, and using this module may break your
--   code unless you are extremely careful.
module Control.Concurrent.Async.Internal

-- | An asynchronous action spawned by <a>async</a> or <a>withAsync</a>.
--   Asynchronous actions are executed in a separate thread, and operations
--   are provided for waiting for asynchronous actions to complete and
--   obtaining their results (see e.g. <a>wait</a>).
data Async a
Async :: {-# UNPACK #-} !ThreadId -> STM (Either SomeException a) -> Async a

-- | Returns the <a>ThreadId</a> of the thread running the given
--   <a>Async</a>.
[asyncThreadId] :: Async a -> {-# UNPACK #-} !ThreadId
[_asyncWait] :: Async a -> STM (Either SomeException a)

-- | Compare two Asyncs that may have different types by their
--   <a>ThreadId</a>.
compareAsyncs :: Async a -> Async b -> Ordering

-- | Spawn an asynchronous action in a separate thread.
--   
--   Like for <a>forkIO</a>, the action may be left running unintentionally
--   (see module-level documentation for details).
--   
--   <b>Use <a>withAsync</a> style functions wherever you can instead!</b>
async :: IO a -> IO (Async a)

-- | Like <a>async</a> but using <a>forkOS</a> internally.
asyncBound :: IO a -> IO (Async a)

-- | Like <a>async</a> but using <a>forkOn</a> internally.
asyncOn :: Int -> IO a -> IO (Async a)

-- | Like <a>async</a> but using <a>forkIOWithUnmask</a> internally. The
--   child thread is passed a function that can be used to unmask
--   asynchronous exceptions.
asyncWithUnmask :: ((forall b. () => IO b -> IO b) -> IO a) -> IO (Async a)

-- | Like <a>asyncOn</a> but using <a>forkOnWithUnmask</a> internally. The
--   child thread is passed a function that can be used to unmask
--   asynchronous exceptions.
asyncOnWithUnmask :: Int -> ((forall b. () => IO b -> IO b) -> IO a) -> IO (Async a)
asyncUsing :: (IO () -> IO ThreadId) -> IO a -> IO (Async a)

-- | Spawn an asynchronous action in a separate thread, and pass its
--   <tt>Async</tt> handle to the supplied function. When the function
--   returns or throws an exception, <a>uninterruptibleCancel</a> is called
--   on the <tt>Async</tt>.
--   
--   <pre>
--   withAsync action inner = mask $ \restore -&gt; do
--     a &lt;- async (restore action)
--     restore (inner a) `finally` uninterruptibleCancel a
--   </pre>
--   
--   This is a useful variant of <a>async</a> that ensures an
--   <tt>Async</tt> is never left running unintentionally.
--   
--   Note: a reference to the child thread is kept alive until the call to
--   <a>withAsync</a> returns, so nesting many <a>withAsync</a> calls
--   requires linear memory.
withAsync :: IO a -> (Async a -> IO b) -> IO b

-- | Like <a>withAsync</a> but uses <a>forkOS</a> internally.
withAsyncBound :: IO a -> (Async a -> IO b) -> IO b

-- | Like <a>withAsync</a> but uses <a>forkOn</a> internally.
withAsyncOn :: Int -> IO a -> (Async a -> IO b) -> IO b

-- | Like <a>withAsync</a> but uses <a>forkIOWithUnmask</a> internally. The
--   child thread is passed a function that can be used to unmask
--   asynchronous exceptions.
withAsyncWithUnmask :: ((forall c. () => IO c -> IO c) -> IO a) -> (Async a -> IO b) -> IO b

-- | Like <a>withAsyncOn</a> but uses <a>forkOnWithUnmask</a> internally.
--   The child thread is passed a function that can be used to unmask
--   asynchronous exceptions
withAsyncOnWithUnmask :: Int -> ((forall c. () => IO c -> IO c) -> IO a) -> (Async a -> IO b) -> IO b
withAsyncUsing :: (IO () -> IO ThreadId) -> IO a -> (Async a -> IO b) -> IO b

-- | Wait for an asynchronous action to complete, and return its value. If
--   the asynchronous action threw an exception, then the exception is
--   re-thrown by <a>wait</a>.
--   
--   <pre>
--   wait = atomically . waitSTM
--   </pre>
wait :: Async a -> IO a

-- | Wait for an asynchronous action to complete, and return either
--   <tt>Left e</tt> if the action raised an exception <tt>e</tt>, or
--   <tt>Right a</tt> if it returned a value <tt>a</tt>.
--   
--   <pre>
--   waitCatch = atomically . waitCatchSTM
--   </pre>
waitCatch :: Async a -> IO (Either SomeException a)

-- | Check whether an <a>Async</a> has completed yet. If it has not
--   completed yet, then the result is <tt>Nothing</tt>, otherwise the
--   result is <tt>Just e</tt> where <tt>e</tt> is <tt>Left x</tt> if the
--   <tt>Async</tt> raised an exception <tt>x</tt>, or <tt>Right a</tt> if
--   it returned a value <tt>a</tt>.
--   
--   <pre>
--   poll = atomically . pollSTM
--   </pre>
poll :: Async a -> IO (Maybe (Either SomeException a))

-- | A version of <a>wait</a> that can be used inside an STM transaction.
waitSTM :: Async a -> STM a

-- | A version of <a>waitCatch</a> that can be used inside an STM
--   transaction.
waitCatchSTM :: Async a -> STM (Either SomeException a)

-- | A version of <a>poll</a> that can be used inside an STM transaction.
pollSTM :: Async a -> STM (Maybe (Either SomeException a))

-- | Cancel an asynchronous action by throwing the <tt>AsyncCancelled</tt>
--   exception to it, and waiting for the <a>Async</a> thread to quit. Has
--   no effect if the <a>Async</a> has already completed.
--   
--   <pre>
--   cancel a = throwTo (asyncThreadId a) AsyncCancelled &lt;* waitCatch a
--   </pre>
--   
--   Note that <a>cancel</a> will not terminate until the thread the
--   <a>Async</a> refers to has terminated. This means that <a>cancel</a>
--   will block for as long said thread blocks when receiving an
--   asynchronous exception.
--   
--   For example, it could block if:
--   
--   <ul>
--   <li>It's executing a foreign call, and thus cannot receive the
--   asynchronous exception;</li>
--   <li>It's executing some cleanup handler after having received the
--   exception, and the handler is blocking.</li>
--   </ul>
cancel :: Async a -> IO ()

-- | Cancel multiple asynchronous actions by throwing the
--   <tt>AsyncCancelled</tt> exception to each of them in turn, then
--   waiting for all the <a>Async</a> threads to complete.
cancelMany :: [Async a] -> IO ()

-- | The exception thrown by <a>cancel</a> to terminate a thread.
data AsyncCancelled
AsyncCancelled :: AsyncCancelled

-- | Cancel an asynchronous action
--   
--   This is a variant of <a>cancel</a>, but it is not interruptible.
uninterruptibleCancel :: Async a -> IO ()

-- | Cancel an asynchronous action by throwing the supplied exception to
--   it.
--   
--   <pre>
--   cancelWith a x = throwTo (asyncThreadId a) x
--   </pre>
--   
--   The notes about the synchronous nature of <a>cancel</a> also apply to
--   <a>cancelWith</a>.
cancelWith :: Exception e => Async a -> e -> IO ()

-- | Wait for any of the supplied asynchronous operations to complete. The
--   value returned is a pair of the <a>Async</a> that completed, and the
--   result that would be returned by <a>wait</a> on that <a>Async</a>. The
--   input list must be non-empty.
--   
--   If multiple <a>Async</a>s complete or have completed, then the value
--   returned corresponds to the first completed <a>Async</a> in the list.
waitAnyCatch :: [Async a] -> IO (Async a, Either SomeException a)

-- | A version of <a>waitAnyCatch</a> that can be used inside an STM
--   transaction.
waitAnyCatchSTM :: [Async a] -> STM (Async a, Either SomeException a)

-- | Like <a>waitAnyCatch</a>, but also cancels the other asynchronous
--   operations as soon as one has completed.
waitAnyCatchCancel :: [Async a] -> IO (Async a, Either SomeException a)

-- | Wait for any of the supplied <tt>Async</tt>s to complete. If the first
--   to complete throws an exception, then that exception is re-thrown by
--   <a>waitAny</a>. The input list must be non-empty.
--   
--   If multiple <a>Async</a>s complete or have completed, then the value
--   returned corresponds to the first completed <a>Async</a> in the list.
waitAny :: [Async a] -> IO (Async a, a)

-- | A version of <a>waitAny</a> that can be used inside an STM
--   transaction.
waitAnySTM :: [Async a] -> STM (Async a, a)

-- | Like <a>waitAny</a>, but also cancels the other asynchronous
--   operations as soon as one has completed.
waitAnyCancel :: [Async a] -> IO (Async a, a)

-- | Wait for the first of two <tt>Async</tt>s to finish.
waitEitherCatch :: Async a -> Async b -> IO (Either (Either SomeException a) (Either SomeException b))

-- | A version of <a>waitEitherCatch</a> that can be used inside an STM
--   transaction.
waitEitherCatchSTM :: Async a -> Async b -> STM (Either (Either SomeException a) (Either SomeException b))

-- | Like <a>waitEitherCatch</a>, but also <a>cancel</a>s both
--   <tt>Async</tt>s before returning.
waitEitherCatchCancel :: Async a -> Async b -> IO (Either (Either SomeException a) (Either SomeException b))

-- | Wait for the first of two <tt>Async</tt>s to finish. If the
--   <tt>Async</tt> that finished first raised an exception, then the
--   exception is re-thrown by <a>waitEither</a>.
waitEither :: Async a -> Async b -> IO (Either a b)

-- | A version of <a>waitEither</a> that can be used inside an STM
--   transaction.
waitEitherSTM :: Async a -> Async b -> STM (Either a b)

-- | Like <a>waitEither</a>, but the result is ignored.
waitEither_ :: Async a -> Async b -> IO ()

-- | A version of <a>waitEither_</a> that can be used inside an STM
--   transaction.
waitEitherSTM_ :: Async a -> Async b -> STM ()

-- | Like <a>waitEither</a>, but also <a>cancel</a>s both <tt>Async</tt>s
--   before returning.
waitEitherCancel :: Async a -> Async b -> IO (Either a b)

-- | Waits for both <tt>Async</tt>s to finish, but if either of them throws
--   an exception before they have both finished, then the exception is
--   re-thrown by <a>waitBoth</a>.
waitBoth :: Async a -> Async b -> IO (a, b)

-- | A version of <a>waitBoth</a> that can be used inside an STM
--   transaction.
waitBothSTM :: Async a -> Async b -> STM (a, b)
data ExceptionInLinkedThread
ExceptionInLinkedThread :: Async a -> SomeException -> ExceptionInLinkedThread

-- | Link the given <tt>Async</tt> to the current thread, such that if the
--   <tt>Async</tt> raises an exception, that exception will be re-thrown
--   in the current thread, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   <a>link</a> ignores <a>AsyncCancelled</a> exceptions thrown in the
--   other thread, so that it's safe to <a>cancel</a> a thread you're
--   linked to. If you want different behaviour, use <a>linkOnly</a>.
link :: Async a -> IO ()

-- | Link the given <tt>Async</tt> to the current thread, such that if the
--   <tt>Async</tt> raises an exception, that exception will be re-thrown
--   in the current thread, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   The supplied predicate determines which exceptions in the target
--   thread should be propagated to the source thread.
linkOnly :: (SomeException -> Bool) -> Async a -> IO ()

-- | Link two <tt>Async</tt>s together, such that if either raises an
--   exception, the same exception is re-thrown in the other
--   <tt>Async</tt>, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   <a>link2</a> ignores <a>AsyncCancelled</a> exceptions, so that it's
--   possible to <a>cancel</a> either thread without cancelling the other.
--   If you want different behaviour, use <a>link2Only</a>.
link2 :: Async a -> Async b -> IO ()

-- | Link two <tt>Async</tt>s together, such that if either raises an
--   exception, the same exception is re-thrown in the other
--   <tt>Async</tt>, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   The supplied predicate determines which exceptions in the target
--   thread should be propagated to the source thread.
link2Only :: (SomeException -> Bool) -> Async a -> Async b -> IO ()
isCancel :: SomeException -> Bool

-- | Run two <tt>IO</tt> actions concurrently, and return the first to
--   finish. The loser of the race is <a>cancel</a>led.
--   
--   <pre>
--   race left right =
--     withAsync left $ \a -&gt;
--     withAsync right $ \b -&gt;
--     waitEither a b
--   </pre>
race :: IO a -> IO b -> IO (Either a b)

-- | Like <a>race</a>, but the result is ignored.
race_ :: IO a -> IO b -> IO ()

-- | Run two <tt>IO</tt> actions concurrently, and return both results. If
--   either action throws an exception at any time, then the other action
--   is <a>cancel</a>led, and the exception is re-thrown by
--   <a>concurrently</a>.
--   
--   <pre>
--   concurrently left right =
--     withAsync left $ \a -&gt;
--     withAsync right $ \b -&gt;
--     waitBoth a b
--   </pre>
concurrently :: IO a -> IO b -> IO (a, b)

-- | Run two <tt>IO</tt> actions concurrently. If both of them end with
--   <tt>Right</tt>, return both results. If one of then ends with
--   <tt>Left</tt>, interrupt the other action and return the
--   <tt>Left</tt>.
concurrentlyE :: IO (Either e a) -> IO (Either e b) -> IO (Either e (a, b))
concurrently' :: IO a -> IO b -> (IO (Either SomeException (Either a b)) -> IO r) -> IO r

-- | <a>concurrently</a>, but ignore the result values
concurrently_ :: IO a -> IO b -> IO ()

-- | Maps an <a>IO</a>-performing function over any <a>Traversable</a> data
--   type, performing all the <tt>IO</tt> 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, <tt>mapConcurrently</tt> works with lists:
--   
--   <pre>
--   pages &lt;- mapConcurrently getURL ["url1", "url2", "url3"]
--   </pre>
--   
--   Take into account that <tt>async</tt> will try to immediately spawn a
--   thread for each element of the <tt>Traversable</tt>, so running this
--   on large inputs without care may lead to resource exhaustion (of
--   memory, file descriptors, or other limited resources).
mapConcurrently :: Traversable t => (a -> IO b) -> t a -> IO (t b)

-- | <a>forConcurrently</a> is <a>mapConcurrently</a> with its arguments
--   flipped
--   
--   <pre>
--   pages &lt;- forConcurrently ["url1", "url2", "url3"] $ \url -&gt; getURL url
--   </pre>
forConcurrently :: Traversable t => t a -> (a -> IO b) -> IO (t b)

-- | <a>mapConcurrently_</a> is <a>mapConcurrently</a> with the return
--   value discarded; a concurrent equivalent of <a>mapM_</a>.
mapConcurrently_ :: Foldable f => (a -> IO b) -> f a -> IO ()

-- | <a>forConcurrently_</a> is <a>forConcurrently</a> with the return
--   value discarded; a concurrent equivalent of <a>forM_</a>.
forConcurrently_ :: Foldable f => f a -> (a -> IO b) -> IO ()

-- | Perform the action in the given number of threads.
replicateConcurrently :: Int -> IO a -> IO [a]

-- | Same as <a>replicateConcurrently</a>, but ignore the results.
replicateConcurrently_ :: Int -> IO a -> IO ()

-- | A value of type <tt>Concurrently a</tt> is an <tt>IO</tt> operation
--   that can be composed with other <tt>Concurrently</tt> values, using
--   the <tt>Applicative</tt> and <tt>Alternative</tt> instances.
--   
--   Calling <tt>runConcurrently</tt> on a value of type <tt>Concurrently
--   a</tt> will execute the <tt>IO</tt> operations it contains
--   concurrently, before delivering the result of type <tt>a</tt>.
--   
--   For example
--   
--   <pre>
--   (page1, page2, page3)
--       &lt;- runConcurrently $ (,,)
--       &lt;$&gt; Concurrently (getURL "url1")
--       &lt;*&gt; Concurrently (getURL "url2")
--       &lt;*&gt; Concurrently (getURL "url3")
--   </pre>
newtype Concurrently a
Concurrently :: IO a -> Concurrently a
[runConcurrently] :: Concurrently a -> IO a

-- | A value of type <tt>ConcurrentlyE e a</tt> is an <tt>IO</tt> operation
--   that can be composed with other <tt>ConcurrentlyE</tt> values, using
--   the <tt>Applicative</tt> instance.
--   
--   Calling <tt>runConcurrentlyE</tt> on a value of type <tt>ConcurrentlyE
--   e a</tt> will execute the <tt>IO</tt> operations it contains
--   concurrently, before delivering either the result of type <tt>a</tt>,
--   or an error of type <tt>e</tt> if one of the actions returns
--   <tt>Left</tt>.
--   
--   | @since 2.2.5
newtype ConcurrentlyE e a
ConcurrentlyE :: IO (Either e a) -> ConcurrentlyE e a
[runConcurrentlyE] :: ConcurrentlyE e a -> IO (Either e a)

-- | Fork a thread that runs the supplied action, and if it raises an
--   exception, re-runs the action. The thread terminates only when the
--   action runs to completion without raising an exception.
forkRepeat :: IO a -> IO ThreadId
catchAll :: IO a -> (SomeException -> IO a) -> IO a
tryAll :: IO a -> IO (Either SomeException a)
rawForkIO :: IO () -> IO ThreadId
rawForkOn :: Int -> IO () -> IO ThreadId
instance GHC.Internal.Base.Alternative Control.Concurrent.Async.Internal.Concurrently
instance GHC.Internal.Base.Applicative Control.Concurrent.Async.Internal.Concurrently
instance GHC.Internal.Base.Applicative (Control.Concurrent.Async.Internal.ConcurrentlyE e)
instance Data.Bifunctor.Bifunctor Control.Concurrent.Async.Internal.ConcurrentlyE
instance GHC.Classes.Eq (Control.Concurrent.Async.Internal.Async a)
instance GHC.Classes.Eq Control.Concurrent.Async.Internal.AsyncCancelled
instance GHC.Internal.Exception.Type.Exception Control.Concurrent.Async.Internal.AsyncCancelled
instance GHC.Internal.Exception.Type.Exception Control.Concurrent.Async.Internal.ExceptionInLinkedThread
instance GHC.Internal.Base.Functor Control.Concurrent.Async.Internal.Async
instance GHC.Internal.Base.Functor Control.Concurrent.Async.Internal.Concurrently
instance GHC.Internal.Base.Functor (Control.Concurrent.Async.Internal.ConcurrentlyE e)
instance Data.Hashable.Class.Hashable (Control.Concurrent.Async.Internal.Async a)
instance (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Monoid a) => GHC.Internal.Base.Monoid (Control.Concurrent.Async.Internal.Concurrently a)
instance (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Monoid a) => GHC.Internal.Base.Monoid (Control.Concurrent.Async.Internal.ConcurrentlyE e a)
instance GHC.Classes.Ord (Control.Concurrent.Async.Internal.Async a)
instance GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Control.Concurrent.Async.Internal.Concurrently a)
instance GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Control.Concurrent.Async.Internal.ConcurrentlyE e a)
instance GHC.Internal.Show.Show Control.Concurrent.Async.Internal.AsyncCancelled
instance GHC.Internal.Show.Show Control.Concurrent.Async.Internal.ExceptionInLinkedThread


-- | This module provides a set of operations for running IO operations
--   asynchronously and waiting for their results. It is a thin layer over
--   the basic concurrency operations provided by
--   <a>Control.Concurrent</a>. The main additional functionality it
--   provides is the ability to wait for the return value of a thread, but
--   the interface also provides some additional safety and robustness over
--   using <tt>forkIO</tt> threads and <tt>MVar</tt> directly.
--   
--   <h2>High-level API</h2>
--   
--   <tt>async</tt>'s high-level API spawns <i>lexically scoped</i>
--   threads, ensuring the following key poperties that make it safer to
--   use than using plain <tt>forkIO</tt>:
--   
--   <ol>
--   <li>No exception is swallowed (waiting for results propagates
--   exceptions).</li>
--   <li>No thread is leaked (left running unintentionally).</li>
--   </ol>
--   
--   (This is done using the <a>bracket</a> pattern to work in presence of
--   synchronous and asynchronous exceptions.)
--   
--   <b>Most practical/production code should only use the high-level
--   API</b>.
--   
--   The basic type is <tt><a>Async</a> a</tt>, which represents an
--   asynchronous <tt>IO</tt> action that will return a value of type
--   <tt>a</tt>, or die with an exception. An <a>Async</a> is a wrapper
--   around a low-level <tt>forkIO</tt> thread.
--   
--   The fundamental function to spawn threads with the high-level API is
--   <a>withAsync</a>.
--   
--   For example, to fetch two web pages at the same time, we could do this
--   (assuming a suitable <tt>getURL</tt> function):
--   
--   <pre>
--   withAsync (getURL url1) $ \a1 -&gt; do
--     withAsync (getURL url2) $ \a2 -&gt; do
--       page1 &lt;- wait a1
--       page2 &lt;- wait a2
--       ...
--   </pre>
--   
--   where <a>withAsync</a> starts the operation in a separate thread, and
--   <a>wait</a> waits for and returns the result.
--   
--   <ul>
--   <li>If the operation throws an exception, then that exception is
--   re-thrown by <a>wait</a>. This ensures property (1): No exception is
--   swallowed.</li>
--   <li>If an exception bubbles up through a <a>withAsync</a>, then the
--   <a>Async</a> it spawned is <a>cancel</a>ed. This ensures property (2):
--   No thread is leaked.</li>
--   </ul>
--   
--   Often we do not care to work manually with <a>Async</a> handles like
--   <tt>a1</tt> and <tt>a2</tt>. Instead, we want to express high-level
--   objectives like performing two or more tasks concurrently, and waiting
--   for one or all of them to finish.
--   
--   For example, the pattern of performing two IO actions concurrently and
--   waiting for both their results is packaged up in a combinator
--   <a>concurrently</a>, so we can further shorten the above example to:
--   
--   <pre>
--   (page1, page2) &lt;- concurrently (getURL url1) (getURL url2)
--   ...
--   </pre>
--   
--   The section <b><i>High-level utilities</i></b> covers the most common
--   high-level objectives, including:
--   
--   <ul>
--   <li>Waiting for 2 results (<a>concurrently</a>).</li>
--   <li>Waiting for many results (<a>mapConcurrently</a> /
--   <a>forConcurrently</a>).</li>
--   <li>Waiting for the first of 2 results (<a>race</a>).</li>
--   <li>Waiting for arbitrary nestings of "all of <i>N</i>" and "the first
--   of <i>N</i>" results with the <a>Concurrently</a> newtype and its
--   <a>Applicative</a> and <tt>Alternative</tt> instances.</li>
--   </ul>
--   
--   Click here to scroll to that section:
--   <a>Control.Concurrent.Async#high-level-utilities</a>.
--   
--   <h2>Low-level API</h2>
--   
--   Some use cases require parallelism that is not lexically scoped.
--   
--   For those, the low-level function <a>async</a> can be used as a direct
--   equivalent of <tt>forkIO</tt>:
--   
--   <pre>
--   -- Do NOT use this code in production, it has a flaw (explained below).
--   do
--     a1 &lt;- async (getURL url1)
--     a2 &lt;- async (getURL url2)
--     page1 &lt;- wait a1
--     page2 &lt;- wait a2
--     ...
--   </pre>
--   
--   In contrast to <a>withAsync</a>, this code has a problem.
--   
--   It still fulfills property (1) in that an exception arising from
--   <tt>getUrl</tt> will be re-thrown by <a>wait</a>, but it does not
--   fulfill property (2). Consider the case when the first <a>wait</a>
--   throws an exception; then the second <a>wait</a> will not happen, and
--   the second <a>async</a> may be left running in the background,
--   possibly indefinitely.
--   
--   <a>withAsync</a> is like <a>async</a>, except that the <a>Async</a> is
--   automatically killed (using <a>uninterruptibleCancel</a>) if the
--   enclosing IO operation returns before it has completed. Furthermore,
--   <a>withAsync</a> allows a tree of threads to be built, such that
--   children are automatically killed if their parents die for any reason.
--   
--   If you need to use the low-level API, ensure that you guarantee
--   property (2) by other means, such as <a>link</a>ing asyncs that need
--   to die together, and protecting against asynchronous exceptions using
--   <a>bracket</a>, <a>mask</a>, or other functions from
--   <a>Control.Exception</a>.
--   
--   <h2>Miscellaneous</h2>
--   
--   The <a>Functor</a> instance can be used to change the result of an
--   <a>Async</a>. For example:
--   
--   <pre>
--   ghci&gt; withAsync (return 3) (\a -&gt; wait (fmap (+1) a))
--   4
--   </pre>
--   
--   <h3>Resource exhaustion</h3>
--   
--   As with all concurrent programming, keep in mind that while Haskell's
--   cooperative ("green") multithreading carries low overhead, spawning
--   too many of them at the same time may lead to resource exhaustion (of
--   memory, file descriptors, or other limited resources), given that the
--   actions running in the threads consume these resources.
module Control.Concurrent.Async

-- | An asynchronous action spawned by <a>async</a> or <a>withAsync</a>.
--   Asynchronous actions are executed in a separate thread, and operations
--   are provided for waiting for asynchronous actions to complete and
--   obtaining their results (see e.g. <a>wait</a>).
data Async a

-- | Spawn an asynchronous action in a separate thread, and pass its
--   <tt>Async</tt> handle to the supplied function. When the function
--   returns or throws an exception, <a>uninterruptibleCancel</a> is called
--   on the <tt>Async</tt>.
--   
--   <pre>
--   withAsync action inner = mask $ \restore -&gt; do
--     a &lt;- async (restore action)
--     restore (inner a) `finally` uninterruptibleCancel a
--   </pre>
--   
--   This is a useful variant of <a>async</a> that ensures an
--   <tt>Async</tt> is never left running unintentionally.
--   
--   Note: a reference to the child thread is kept alive until the call to
--   <a>withAsync</a> returns, so nesting many <a>withAsync</a> calls
--   requires linear memory.
withAsync :: IO a -> (Async a -> IO b) -> IO b

-- | Like <a>withAsync</a> but uses <a>forkOS</a> internally.
withAsyncBound :: IO a -> (Async a -> IO b) -> IO b

-- | Like <a>withAsync</a> but uses <a>forkOn</a> internally.
withAsyncOn :: Int -> IO a -> (Async a -> IO b) -> IO b

-- | Like <a>withAsync</a> but uses <a>forkIOWithUnmask</a> internally. The
--   child thread is passed a function that can be used to unmask
--   asynchronous exceptions.
withAsyncWithUnmask :: ((forall c. () => IO c -> IO c) -> IO a) -> (Async a -> IO b) -> IO b

-- | Like <a>withAsyncOn</a> but uses <a>forkOnWithUnmask</a> internally.
--   The child thread is passed a function that can be used to unmask
--   asynchronous exceptions
withAsyncOnWithUnmask :: Int -> ((forall c. () => IO c -> IO c) -> IO a) -> (Async a -> IO b) -> IO b

-- | Wait for an asynchronous action to complete, and return its value. If
--   the asynchronous action threw an exception, then the exception is
--   re-thrown by <a>wait</a>.
--   
--   <pre>
--   wait = atomically . waitSTM
--   </pre>
wait :: Async a -> IO a

-- | Check whether an <a>Async</a> has completed yet. If it has not
--   completed yet, then the result is <tt>Nothing</tt>, otherwise the
--   result is <tt>Just e</tt> where <tt>e</tt> is <tt>Left x</tt> if the
--   <tt>Async</tt> raised an exception <tt>x</tt>, or <tt>Right a</tt> if
--   it returned a value <tt>a</tt>.
--   
--   <pre>
--   poll = atomically . pollSTM
--   </pre>
poll :: Async a -> IO (Maybe (Either SomeException a))

-- | Wait for an asynchronous action to complete, and return either
--   <tt>Left e</tt> if the action raised an exception <tt>e</tt>, or
--   <tt>Right a</tt> if it returned a value <tt>a</tt>.
--   
--   <pre>
--   waitCatch = atomically . waitCatchSTM
--   </pre>
waitCatch :: Async a -> IO (Either SomeException a)

-- | Returns the <a>ThreadId</a> of the thread running the given
--   <a>Async</a>.
asyncThreadId :: Async a -> ThreadId

-- | Cancel an asynchronous action by throwing the <tt>AsyncCancelled</tt>
--   exception to it, and waiting for the <a>Async</a> thread to quit. Has
--   no effect if the <a>Async</a> has already completed.
--   
--   <pre>
--   cancel a = throwTo (asyncThreadId a) AsyncCancelled &lt;* waitCatch a
--   </pre>
--   
--   Note that <a>cancel</a> will not terminate until the thread the
--   <a>Async</a> refers to has terminated. This means that <a>cancel</a>
--   will block for as long said thread blocks when receiving an
--   asynchronous exception.
--   
--   For example, it could block if:
--   
--   <ul>
--   <li>It's executing a foreign call, and thus cannot receive the
--   asynchronous exception;</li>
--   <li>It's executing some cleanup handler after having received the
--   exception, and the handler is blocking.</li>
--   </ul>
cancel :: Async a -> IO ()

-- | Cancel multiple asynchronous actions by throwing the
--   <tt>AsyncCancelled</tt> exception to each of them in turn, then
--   waiting for all the <a>Async</a> threads to complete.
cancelMany :: [Async a] -> IO ()

-- | Cancel an asynchronous action
--   
--   This is a variant of <a>cancel</a>, but it is not interruptible.
uninterruptibleCancel :: Async a -> IO ()

-- | Cancel an asynchronous action by throwing the supplied exception to
--   it.
--   
--   <pre>
--   cancelWith a x = throwTo (asyncThreadId a) x
--   </pre>
--   
--   The notes about the synchronous nature of <a>cancel</a> also apply to
--   <a>cancelWith</a>.
cancelWith :: Exception e => Async a -> e -> IO ()

-- | The exception thrown by <a>cancel</a> to terminate a thread.
data AsyncCancelled
AsyncCancelled :: AsyncCancelled

-- | Run two <tt>IO</tt> actions concurrently, and return the first to
--   finish. The loser of the race is <a>cancel</a>led.
--   
--   <pre>
--   race left right =
--     withAsync left $ \a -&gt;
--     withAsync right $ \b -&gt;
--     waitEither a b
--   </pre>
race :: IO a -> IO b -> IO (Either a b)

-- | Like <a>race</a>, but the result is ignored.
race_ :: IO a -> IO b -> IO ()

-- | Run two <tt>IO</tt> actions concurrently, and return both results. If
--   either action throws an exception at any time, then the other action
--   is <a>cancel</a>led, and the exception is re-thrown by
--   <a>concurrently</a>.
--   
--   <pre>
--   concurrently left right =
--     withAsync left $ \a -&gt;
--     withAsync right $ \b -&gt;
--     waitBoth a b
--   </pre>
concurrently :: IO a -> IO b -> IO (a, b)

-- | <a>concurrently</a>, but ignore the result values
concurrently_ :: IO a -> IO b -> IO ()

-- | Maps an <a>IO</a>-performing function over any <a>Traversable</a> data
--   type, performing all the <tt>IO</tt> 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, <tt>mapConcurrently</tt> works with lists:
--   
--   <pre>
--   pages &lt;- mapConcurrently getURL ["url1", "url2", "url3"]
--   </pre>
--   
--   Take into account that <tt>async</tt> will try to immediately spawn a
--   thread for each element of the <tt>Traversable</tt>, so running this
--   on large inputs without care may lead to resource exhaustion (of
--   memory, file descriptors, or other limited resources).
mapConcurrently :: Traversable t => (a -> IO b) -> t a -> IO (t b)

-- | <a>forConcurrently</a> is <a>mapConcurrently</a> with its arguments
--   flipped
--   
--   <pre>
--   pages &lt;- forConcurrently ["url1", "url2", "url3"] $ \url -&gt; getURL url
--   </pre>
forConcurrently :: Traversable t => t a -> (a -> IO b) -> IO (t b)

-- | <a>mapConcurrently_</a> is <a>mapConcurrently</a> with the return
--   value discarded; a concurrent equivalent of <a>mapM_</a>.
mapConcurrently_ :: Foldable f => (a -> IO b) -> f a -> IO ()

-- | <a>forConcurrently_</a> is <a>forConcurrently</a> with the return
--   value discarded; a concurrent equivalent of <a>forM_</a>.
forConcurrently_ :: Foldable f => f a -> (a -> IO b) -> IO ()

-- | Perform the action in the given number of threads.
replicateConcurrently :: Int -> IO a -> IO [a]

-- | Same as <a>replicateConcurrently</a>, but ignore the results.
replicateConcurrently_ :: Int -> IO a -> IO ()

-- | A value of type <tt>Concurrently a</tt> is an <tt>IO</tt> operation
--   that can be composed with other <tt>Concurrently</tt> values, using
--   the <tt>Applicative</tt> and <tt>Alternative</tt> instances.
--   
--   Calling <tt>runConcurrently</tt> on a value of type <tt>Concurrently
--   a</tt> will execute the <tt>IO</tt> operations it contains
--   concurrently, before delivering the result of type <tt>a</tt>.
--   
--   For example
--   
--   <pre>
--   (page1, page2, page3)
--       &lt;- runConcurrently $ (,,)
--       &lt;$&gt; Concurrently (getURL "url1")
--       &lt;*&gt; Concurrently (getURL "url2")
--       &lt;*&gt; Concurrently (getURL "url3")
--   </pre>
newtype Concurrently a
Concurrently :: IO a -> Concurrently a
[runConcurrently] :: Concurrently a -> IO a

-- | Run two <tt>IO</tt> actions concurrently. If both of them end with
--   <tt>Right</tt>, return both results. If one of then ends with
--   <tt>Left</tt>, interrupt the other action and return the
--   <tt>Left</tt>.
concurrentlyE :: IO (Either e a) -> IO (Either e b) -> IO (Either e (a, b))

-- | A value of type <tt>ConcurrentlyE e a</tt> is an <tt>IO</tt> operation
--   that can be composed with other <tt>ConcurrentlyE</tt> values, using
--   the <tt>Applicative</tt> instance.
--   
--   Calling <tt>runConcurrentlyE</tt> on a value of type <tt>ConcurrentlyE
--   e a</tt> will execute the <tt>IO</tt> operations it contains
--   concurrently, before delivering either the result of type <tt>a</tt>,
--   or an error of type <tt>e</tt> if one of the actions returns
--   <tt>Left</tt>.
--   
--   | @since 2.2.5
newtype ConcurrentlyE e a
ConcurrentlyE :: IO (Either e a) -> ConcurrentlyE e a
[runConcurrentlyE] :: ConcurrentlyE e a -> IO (Either e a)

-- | Compare two Asyncs that may have different types by their
--   <a>ThreadId</a>.
compareAsyncs :: Async a -> Async b -> Ordering

-- | A version of <a>wait</a> that can be used inside an STM transaction.
waitSTM :: Async a -> STM a

-- | A version of <a>poll</a> that can be used inside an STM transaction.
pollSTM :: Async a -> STM (Maybe (Either SomeException a))

-- | A version of <a>waitCatch</a> that can be used inside an STM
--   transaction.
waitCatchSTM :: Async a -> STM (Either SomeException a)

-- | Wait for any of the supplied <tt>Async</tt>s to complete. If the first
--   to complete throws an exception, then that exception is re-thrown by
--   <a>waitAny</a>. The input list must be non-empty.
--   
--   If multiple <a>Async</a>s complete or have completed, then the value
--   returned corresponds to the first completed <a>Async</a> in the list.
waitAny :: [Async a] -> IO (Async a, a)

-- | Wait for any of the supplied asynchronous operations to complete. The
--   value returned is a pair of the <a>Async</a> that completed, and the
--   result that would be returned by <a>wait</a> on that <a>Async</a>. The
--   input list must be non-empty.
--   
--   If multiple <a>Async</a>s complete or have completed, then the value
--   returned corresponds to the first completed <a>Async</a> in the list.
waitAnyCatch :: [Async a] -> IO (Async a, Either SomeException a)

-- | Like <a>waitAny</a>, but also cancels the other asynchronous
--   operations as soon as one has completed.
waitAnyCancel :: [Async a] -> IO (Async a, a)

-- | Like <a>waitAnyCatch</a>, but also cancels the other asynchronous
--   operations as soon as one has completed.
waitAnyCatchCancel :: [Async a] -> IO (Async a, Either SomeException a)

-- | Wait for the first of two <tt>Async</tt>s to finish. If the
--   <tt>Async</tt> that finished first raised an exception, then the
--   exception is re-thrown by <a>waitEither</a>.
waitEither :: Async a -> Async b -> IO (Either a b)

-- | Wait for the first of two <tt>Async</tt>s to finish.
waitEitherCatch :: Async a -> Async b -> IO (Either (Either SomeException a) (Either SomeException b))

-- | Like <a>waitEither</a>, but also <a>cancel</a>s both <tt>Async</tt>s
--   before returning.
waitEitherCancel :: Async a -> Async b -> IO (Either a b)

-- | Like <a>waitEitherCatch</a>, but also <a>cancel</a>s both
--   <tt>Async</tt>s before returning.
waitEitherCatchCancel :: Async a -> Async b -> IO (Either (Either SomeException a) (Either SomeException b))

-- | Like <a>waitEither</a>, but the result is ignored.
waitEither_ :: Async a -> Async b -> IO ()

-- | Waits for both <tt>Async</tt>s to finish, but if either of them throws
--   an exception before they have both finished, then the exception is
--   re-thrown by <a>waitBoth</a>.
waitBoth :: Async a -> Async b -> IO (a, b)

-- | A version of <a>waitAny</a> that can be used inside an STM
--   transaction.
waitAnySTM :: [Async a] -> STM (Async a, a)

-- | A version of <a>waitAnyCatch</a> that can be used inside an STM
--   transaction.
waitAnyCatchSTM :: [Async a] -> STM (Async a, Either SomeException a)

-- | A version of <a>waitEither</a> that can be used inside an STM
--   transaction.
waitEitherSTM :: Async a -> Async b -> STM (Either a b)

-- | A version of <a>waitEitherCatch</a> that can be used inside an STM
--   transaction.
waitEitherCatchSTM :: Async a -> Async b -> STM (Either (Either SomeException a) (Either SomeException b))

-- | A version of <a>waitEither_</a> that can be used inside an STM
--   transaction.
waitEitherSTM_ :: Async a -> Async b -> STM ()

-- | A version of <a>waitBoth</a> that can be used inside an STM
--   transaction.
waitBothSTM :: Async a -> Async b -> STM (a, b)

-- | Spawn an asynchronous action in a separate thread.
--   
--   Like for <a>forkIO</a>, the action may be left running unintentionally
--   (see module-level documentation for details).
--   
--   <b>Use <a>withAsync</a> style functions wherever you can instead!</b>
async :: IO a -> IO (Async a)

-- | Like <a>async</a> but using <a>forkOS</a> internally.
asyncBound :: IO a -> IO (Async a)

-- | Like <a>async</a> but using <a>forkOn</a> internally.
asyncOn :: Int -> IO a -> IO (Async a)

-- | Like <a>async</a> but using <a>forkIOWithUnmask</a> internally. The
--   child thread is passed a function that can be used to unmask
--   asynchronous exceptions.
asyncWithUnmask :: ((forall b. () => IO b -> IO b) -> IO a) -> IO (Async a)

-- | Like <a>asyncOn</a> but using <a>forkOnWithUnmask</a> internally. The
--   child thread is passed a function that can be used to unmask
--   asynchronous exceptions.
asyncOnWithUnmask :: Int -> ((forall b. () => IO b -> IO b) -> IO a) -> IO (Async a)

-- | Link the given <tt>Async</tt> to the current thread, such that if the
--   <tt>Async</tt> raises an exception, that exception will be re-thrown
--   in the current thread, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   <a>link</a> ignores <a>AsyncCancelled</a> exceptions thrown in the
--   other thread, so that it's safe to <a>cancel</a> a thread you're
--   linked to. If you want different behaviour, use <a>linkOnly</a>.
link :: Async a -> IO ()

-- | Link the given <tt>Async</tt> to the current thread, such that if the
--   <tt>Async</tt> raises an exception, that exception will be re-thrown
--   in the current thread, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   The supplied predicate determines which exceptions in the target
--   thread should be propagated to the source thread.
linkOnly :: (SomeException -> Bool) -> Async a -> IO ()

-- | Link two <tt>Async</tt>s together, such that if either raises an
--   exception, the same exception is re-thrown in the other
--   <tt>Async</tt>, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   <a>link2</a> ignores <a>AsyncCancelled</a> exceptions, so that it's
--   possible to <a>cancel</a> either thread without cancelling the other.
--   If you want different behaviour, use <a>link2Only</a>.
link2 :: Async a -> Async b -> IO ()

-- | Link two <tt>Async</tt>s together, such that if either raises an
--   exception, the same exception is re-thrown in the other
--   <tt>Async</tt>, wrapped in <a>ExceptionInLinkedThread</a>.
--   
--   The supplied predicate determines which exceptions in the target
--   thread should be propagated to the source thread.
link2Only :: (SomeException -> Bool) -> Async a -> Async b -> IO ()
data ExceptionInLinkedThread
ExceptionInLinkedThread :: Async a -> SomeException -> ExceptionInLinkedThread
