data-ivar-0.30: Write-once variables with concurrency support

Portabilitypresumably portable
MaintainerLuke Palmer <>



An IVar is an write-once variable (the name comes from "immutable variable"). In addition to encapsulating this common idiom, it also provides a way to block on multiple variables simultaneously, resuming when the first of them is written.

This module is careful not to create memory leaks, and prefers to maintain good long-term memory performance than to be super-fast. It should be reasonably fast though.

This module is designed to be imported qualified, as in:

 import qualified Data.IVar as IVar


 import qualified Data.IVar as IVar
 import Control.Concurrent
 main = do
    iv <-
    iv' <-
    forkIO $ threadDelay 10000000 >> IVar.write iv' "my spoon is too big"
    let merger = iv `mplus` iv'
    print =<< IVar.nonblocking merger   -- most likely "Nothing"
    print =<< IVar.blocking merger      -- waits a while, then prints
    IVar.write iv' "i am a banana"      -- throws error "IVar written twice"



data IVar a Source

A write-once variable.

new :: IO (IVar a)Source

Create a new empty IVar.


Write a value to an IVar. If the IVar already has a value, throws an error "Attempt to write to an IVar twice".

read :: IVar a -> Reader aSource

Read an IVar into the Reader functor. Pass this to blocking or nonblocking to extract the value.

data Reader a Source

Reader is a functor (also monad) for reading IVars. This provides composability when blocking on the first of a set of IVars, as you can block on several IVars of different types.

The MonadPlus and Monoid instances for Reader are equivalent. It tries the left action ; if it blocks, then it tries the right action ; if it blocks, then the whole action blocks until one of the two is available.

nonblocking :: Reader a -> IO (Maybe a)Source

Run a reader nonblocking. Returns Just x if a value x is available, Nothing otherwise.

blocking :: Reader a -> IO aSource

Block on a reader. Returns the value as soon as it is available.

combo :: Reader a -> IO (Either a (IO a))Source

Combination nonblocking and blocking read. combo r Returns Left x if the value is available now, otherwise returns Right (blocking r). This is more efficient than using nonblocking and blocking in sequence (it only evaluates the Reader once).