APISTM.MVar

STM.MVar

A transactional variable that is either full or empty, after Haskell’s TMVar.

Taking from an empty MVar or putting into a full one retries, so these operations block inside STM.atomically until another task’s commit makes them possible, and they combine with other transactions and STM.orElse. An MVar a serves as a one-shot result slot, a handoff between tasks, and, as MVar (), a mutex.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome {
    slot = STM.atomically { MVar.empty () }
    worker = Async.spawn { STM.atomically { MVar.put slot (6 * 7) } }
    STM.atomically { MVar.take slot }
    }
result == Completed 42

MVar

type MVar aSource

A variable holding at most one a. Like STM.Var, it may be shared by any number of tasks and has no equality or Show.

empty

empty : () ->{STM} MVar aSource

An empty variable.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

Async.runOutcome { STM.atomically { MVar.isEmpty (MVar.empty ()) } } == Completed True

isEmpty

isEmpty : MVar a ->{STM} BoolSource

Whether the variable is empty.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

Async.runOutcome { STM.atomically { MVar.isEmpty (MVar.new 0) } } == Completed False

new

new : a ->{STM} MVar aSource

A full variable holding value.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

Async.runOutcome { STM.atomically { MVar.read (MVar.new "ready") } } == Completed "ready"

put

put : MVar a -> a ->{STM} ()Source

Fills the variable with value; retries while it is full.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome { STM.atomically { box = MVar.empty (); MVar.put box "in"; MVar.read box } }
result == Completed "in"

read

read : MVar a ->{STM} aSource

The value, leaving the variable full; retries while it is empty.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome { STM.atomically { box = MVar.new 3; first = MVar.read box; (first, MVar.take box) } }
result == Completed (3, 3)

swap

swap : MVar a -> a ->{STM} aSource

Replaces the value with next and answers the one it replaced; retries while the variable is empty.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome { STM.atomically { box = MVar.new "old"; previous = MVar.swap box "new"; (previous, MVar.read box) } }
result == Completed ("old", "new")

take

take : MVar a ->{STM} aSource

Takes the value, leaving the variable empty; retries while it is empty.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome { STM.atomically { box = MVar.new 1; value = MVar.take box; (value, MVar.isEmpty box) } }
result == Completed (1, True)

tryPut

tryPut : MVar a -> a ->{STM} BoolSource

Fills the variable with value if it is empty, answering whether it did, without retrying.

import Async exposing (Outcome(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome { STM.atomically { box = MVar.empty (); first = MVar.tryPut box 1; second = MVar.tryPut box 2; (first, second, MVar.read box) } }
result == Completed (True, False, 1)

tryRead

tryRead : MVar a ->{STM} Maybe aSource

The value if there is one, leaving the variable as it is, without retrying.

import Async exposing (Outcome(..))
import Maybe exposing (Maybe(..))
import STM
import STM.MVar as MVar

Async.runOutcome { STM.atomically { MVar.tryRead (MVar.new 'x') } } == Completed (Just 'x')

tryTake

tryTake : MVar a ->{STM} Maybe aSource

Takes the value if there is one, leaving the variable empty, without retrying.

import Async exposing (Outcome(..))
import Maybe exposing (Maybe(..))
import STM
import STM.MVar as MVar

result = Async.runOutcome { STM.atomically { box = MVar.new 5; first = MVar.tryTake box; (first, MVar.tryTake box) } }
result == Completed (Just 5, Nothing)