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)
