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

Modulebase-4.20.2.0Haskell2010

GHC.IORef

The IORef type

  • 1 type
  • 10 values
  • Packagebase-4.20.2.0
  • Exports11
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceIORef.hs
newtypenewtype IORef a
#

A mutable variable in the IO monad.

Example11 expressions
import GHC.Internal.Data.IORefr <- newIORef 0readIORef r0writeIORef r 1readIORef r1atomicWriteIORef r 2readIORef r2modifyIORef' r (+ 1)readIORef r3atomicModifyIORef' r (\a -> (a + 1, ()))readIORef r4

See also STRef and Control.Concurrent.MVar.MVar.

Constructors

Instances1Eq
  • Eq (IORef a)Defined in ghc-internal-9.1003.0 · GHC.Internal.IORef

    Pointer equality.

valuereadIORef :: IORef a -> IO a
#

Read the value of an IORef.

Beware that the CPU executing a thread can reorder reads or writes to independent locations. See Data.IORef#memmodel for more details.

valuewriteIORef :: IORef a -> a -> IO ()
#

Write a new value into an IORef.

This function does not create a memory barrier and can be reordered with other independent reads and writes within a thread, which may cause issues for multithreaded execution. In these cases, consider using atomicWriteIORef instead. See Data.IORef#memmodel for more details.

valueatomicModifyIORef2Lazy :: IORef a -> (a -> (a, b)) -> IO (a, (a, b))
#

Atomically apply a function to the contents of an IORef, installing its first component in the IORef and returning the old contents and the result of applying the function. The result of the function application (the pair) is not forced. As a result, this can lead to memory leaks. It is generally better to use atomicModifyIORef2.

valueatomicModifyIORef2 :: IORef a -> (a -> (a, b)) -> IO (a, (a, b))
#

Atomically apply a function to the contents of an IORef, installing its first component in the IORef and returning the old contents and the result of applying the function. The result of the function application (the pair) is forced, but neither of its components is.

valueatomicModifyIORefLazy_ :: IORef a -> (a -> a) -> IO (a, a)
#

Atomically apply a function to the contents of an IORef and return the old and new values. The result of the function is not forced. As this can lead to a memory leak, it is usually better to use atomicModifyIORef'_.

valueatomicModifyIORef'_ :: IORef a -> (a -> a) -> IO (a, a)
#

Atomically apply a function to the contents of an IORef and return the old and new values. The result of the function is forced.

valueatomicModifyIORef' :: IORef a -> (a -> (a, b)) -> IO b
#

A strict version of atomicModifyIORef. This forces both the value stored in the IORef and the value returned.

Conceptually,

atomicModifyIORef' ref f = do
  -- Begin atomic block
  old <- readIORef ref
  let r = f old
      new = fst r
  writeIORef ref new
  -- End atomic block
  case r of
    (!_new, !res) -> pure res

The actions in the "atomic block" are not subject to interference by other threads. In particular, the value in the IORef cannot change between the readIORef and writeIORef invocations.

The new value is installed in the IORef before either value is forced. So

atomicModifyIORef' ref (x -> (x+1, undefined))

will increment the IORef and then throw an exception in the calling thread.

atomicModifyIORef' ref (x -> (undefined, x))

and

atomicModifyIORef' ref (_ -> undefined)

will each raise an exception in the calling thread, but will also install the bottoming value in the IORef, where it may be read by other threads.

This function imposes a memory barrier, preventing reordering around the "atomic block"; see Data.IORef#memmodel for details.