HORIZON HASKELLDocslts/ghc-10.0.x8fef28d2026-11-02Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8fef28d · 2026-11-02

Moduleeffectful-2.7.1.0GHC2021

Effectful.Concurrent.Async

Contents
  1. Effect
  2. Handlers
  3. Asynchronous actions
  4. High-level API
  5. Spawning with automatic cancelation
  6. Querying Asyncs
  7. High-level utilities
  8. Concurrently
  9. Conc
  10. Pooled concurrency
  11. Specialised operations
  12. STM operations
  13. Waiting for multiple Asyncs
  14. Waiting for multiple Asyncs in STM
  15. Low-level API
  16. Spawning (low-level API)
  17. Linking
Synopsis

Effect

datadata Concurrent (a :: Type -> Type) b

Provide the ability to run Eff computations concurrently in multiple threads and communicate between them.

Warning: unless you stick to high level functions from the withAsync family, the Concurrent effect makes it possible to escape the scope of any scoped effect operation. Consider the following:

Example1 expression
import Effectful.Reader.Static qualified as R
Example1 expression
printAsk msg = liftIO . putStrLn . (msg ++) . (": " ++) =<< R.ask
Example1 expression
:{  runEff . R.runReader "GLOBAL" . runConcurrent $ do    a <- R.local (const "LOCAL") $ do      a <- async $ do        printAsk "child (first)"        threadDelay 20000        printAsk "child (second)"      threadDelay 10000      printAsk "parent (inside)"      pure a    printAsk "parent (outside)"    wait a:}child (first): LOCALparent (inside): LOCALparent (outside): GLOBALchild (second): LOCAL

Note that the asynchronous computation doesn't respect the scope of local, i.e. the child thread still behaves like it's inside the local block, even though the parent thread already got out of it.

This is because the value provided by the Reader effect is thread local, i.e. each thread manages its own version of it. For the Reader it is the only reasonable behavior, it wouldn't be very useful if its "read only" value was affected by calls to local from its parent or child threads.

However, the cut isn't so clear if it comes to effects that provide access to a mutable state. That's why statically dispatched State and Writer effects come in two flavors, local and shared:

Example2 expressions
import Effectful.State.Static.Local qualified as SL:{  runEff . SL.execState "Hi" . runConcurrent $ do    replicateConcurrently_ 3 $ SL.modify (++ "!"):}"Hi"
Example2 expressions
import Effectful.State.Static.Shared qualified as SS:{  runEff . SS.execState "Hi" . runConcurrent $ do    replicateConcurrently_ 3 $ SS.modify (++ "!"):}"Hi!!!"

In the first example state updates made concurrently are not reflected in the parent thread because the value is thread local, but in the second example they are, because the value is shared.

Instances2DispatchOf, StaticRep

Handlers

Asynchronous actions

datadata Async a

An asynchronous action spawned by async or withAsync. 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. wait).

Instances4Functor, Eq, Ord, Hashable
  • Functor AsyncDefined in async-2.2.6 · Control.Concurrent.Async.Internal
  • Eq (Async a)Defined in async-2.2.6 · Control.Concurrent.Async.Internal
  • Ord (Async a)Defined in async-2.2.6 · Control.Concurrent.Async.Internal
  • Hashable (Async a)Defined in async-2.2.6 · Control.Concurrent.Async.Internal

High-level API

Spawning with automatic cancelation

Querying Asyncs

High-level utilities

Concurrently

newtypenewtype Concurrently (es :: [Effect]) a

Lifted Concurrently.

Constructors

Instances5Functor, Applicative, Alternative, Semigroup, Monoid

Conc

datadata Conc (a :: [Effect]) b where

Lifted Conc.

Instances5Functor, Applicative, Alternative, Semigroup, Monoid
  • Functor (Conc es)Defined in effectful-2.7.1.0 · Effectful.Concurrent.Async
  • Applicative (Conc es)Defined in effectful-2.7.1.0 · Effectful.Concurrent.Async
  • Alternative (Conc es)Defined in effectful-2.7.1.0 · Effectful.Concurrent.Async
  • Semigroup a => Semigroup (Conc es a)Defined in effectful-2.7.1.0 · Effectful.Concurrent.Async
  • Monoid a => Monoid (Conc es a)Defined in effectful-2.7.1.0 · Effectful.Concurrent.Async
datadata ConcException

Things that can go wrong in the structure of a Conc. These are programmer errors.

Instances6Eq, Ord, Show, Generic, Exception, Rep

Pooled concurrency

Specialised operations

STM operations

Waiting for multiple Asyncs

Waiting for multiple Asyncs in STM

Low-level API

Spawning (low-level API)

Linking