HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduleeffectful-2.3.0.0Haskell2010

Effectful.Concurrent.MVar

  • 2 types
  • 18 values

Effect

1 declaration
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 qualified Effectful.Reader.Static 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 qualified Effectful.State.Static.Local as SL:{  runEff . SL.execState "Hi" . runConcurrent $ do    replicateConcurrently_ 3 $ SL.modify (++ "!"):}"Hi"
Example2 expressions
import qualified Effectful.State.Static.Shared 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

MVar

18 declarations
datadata MVar a
#

An MVar (pronounced "em-var") is a synchronising variable, used for communication between concurrent threads. It can be thought of as a box, which may be empty or full.

Instances3NFData1, Eq, NFData
  • NFData1 MVarDefined in deepseq-1.5.0.0 · Control.DeepSeq
  • Eq (MVar a)Defined in ghc-internal-9.1003.0 · GHC.Internal.MVar

    Compares the underlying pointers.

  • NFData (MVar a)Defined in deepseq-1.5.0.0 · Control.DeepSeq

    NOTE: Only strict in the reference and not the referenced value.