Concurrent type alias #
A computation that produces a $\text{Task}\ \alpha$ without blocking the calling OS thread.
$$\text{Concurrent}\ \alpha \triangleq \text{BaseIO}\ (\text{Task}\ \alpha)$$
Compose with BaseIO.bindTask to chain continuations as tasks.
Any function returning Concurrent α is non-blocking by construction.
Equations
Instances For
MVar internals #
MVar structure #
A synchronisation variable that is either empty or holds a value.
$\text{MVar}$ is the fundamental building block for concurrent data structures. All blocking is promise-based: waiting tasks are dormant promises, not blocked OS threads. This allows scaling to millions of concurrent tasks.
Constraint: Blocking operations (take, read, swap, etc.) require
[Nonempty α] for IO.Promise construction.
Modelled after Haskell's Control.Concurrent.MVar.
Instances For
Construction #
Create a new $\text{MVar}$ containing value $a$.
$$\text{new} : \alpha \to \text{BaseIO}\ (\text{MVar}\ \alpha)$$
Equations
Instances For
Create a new empty $\text{MVar}$.
$$\text{newEmpty} : \text{BaseIO}\ (\text{MVar}\ \alpha)$$
Equations
Instances For
Internal helpers #
Core async operations (non-blocking) #
Take the value from the MVar, leaving it empty. If the MVar is empty,
the caller becomes a dormant promise until a put fills it.
$$\text{take} : \text{MVar}\ \alpha \to \text{BaseIO}\ (\text{Task}\ \alpha)$$
Fairness: Takers are served in FIFO order from Std.Queue.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Put a value into the MVar. If the MVar is full, the caller becomes a
dormant promise until a take empties it.
$$\text{put} : \text{MVar}\ \alpha \to \alpha \to \text{BaseIO}\ (\text{Task}\ \text{Unit})$$
Fairness: Putters are served in FIFO order from Std.Queue.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Read the value without removing it. If empty, waits like take then
puts the value back.
$$\text{read} : \text{MVar}\ \alpha \to \text{BaseIO}\ (\text{Task}\ \alpha)$$
Equations
Instances For
Swap the value in the MVar: take the old, put the new.
$$\text{swap} : \text{MVar}\ \alpha \to \alpha \to \text{BaseIO}\ (\text{Task}\ \alpha)$$
Returns the old value.
Equations
Instances For
Apply a function $f$ to the MVar contents and return a result.
$$\text{withMVar} : \text{MVar}\ \alpha \to (\alpha \to \text{BaseIO}\ (\alpha \times \beta)) \to \text{BaseIO}\ (\text{Task}\ \beta)$$
Takes the value, applies $f$, puts back $\pi_1(f(a))$, returns $\pi_2(f(a))$. If $f$ throws, the MVar remains empty (matching Haskell semantics).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Modify the MVar contents without returning a result.
$$\text{modify\_} : \text{MVar}\ \alpha \to (\alpha \to \text{BaseIO}\ \alpha) \to \text{BaseIO}\ (\text{Task}\ \text{Unit})$$
Instances For
Try operations (non-blocking, immediate) #
Try to take the value. Returns some v immediately if full, none if empty.
$$\text{tryTake} : \text{MVar}\ \alpha \to \text{BaseIO}\ (\text{Option}\ \alpha)$$
Equations
- One or more equations did not get rendered due to their size.
Instances For
Try to put a value. Returns true if successful, false if full.
$$\text{tryPut} : \text{MVar}\ \alpha \to \alpha \to \text{BaseIO}\ \text{Bool}$$
Equations
- One or more equations did not get rendered due to their size.
Instances For
Try to read the value without removing it.
$$\text{tryRead} : \text{MVar}\ \alpha \to \text{BaseIO}\ (\text{Option}\ \alpha)$$
Equations
- mv.tryRead = (Control.Concurrent.MVar.state✝ mv).atomically do let __do_lift ← get pure (Control.Concurrent.MVarState.value✝ __do_lift)
Instances For
Check if the MVar is empty. This is a snapshot — may be stale by the time you act on it.
$$\text{isEmpty} : \text{MVar}\ \alpha \to \text{BaseIO}\ \text{Bool}$$
Equations
- mv.isEmpty = (Control.Concurrent.MVar.state✝ mv).atomically do let __do_lift ← get pure (Control.Concurrent.MVarState.value✝ __do_lift).isNone
Instances For
Sync wrappers (convenience — blocks OS thread) #
Take the value, blocking the OS thread until available.
$$\text{takeSync} : \text{MVar}\ \alpha \to \text{BaseIO}\ \alpha$$
Prefer take (async) for scalable code.
Instances For
Put a value, blocking the OS thread until the MVar is empty.
$$\text{putSync} : \text{MVar}\ \alpha \to \alpha \to \text{BaseIO}\ \text{Unit}$$
Prefer put (async) for scalable code.
Instances For
Read the value, blocking the OS thread until available.
$$\text{readSync} : \text{MVar}\ \alpha \to \text{BaseIO}\ \alpha$$
Prefer read (async) for scalable code.
Instances For
Fairness properties (documented) #
FIFO ordering: Elements dequeued from Std.Queue come out in insertion
order. MVar always enqueues at the back and dequeues from the front,
so waiters are served in FIFO order.
take_resolves_on_put: If an MVar is empty with a taker waiting, a
subsequent put resolves the head taker's promise with the put value.
no_lost_wakeups: Every put on an empty MVar either fills it or wakes
exactly one taker. Every take on a full MVar either empties it or wakes
exactly one putter.