    {-# LANGUAGE Unsafe #-}
    {-# LANGUAGE NoImplicitPrelude, MagicHash, AutoDeriveTypeable #-}
    {-# OPTIONS_GHC -funbox-strict-fields #-}
    {-# OPTIONS_HADDOCK hide #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.IORef
    -- Copyright   :  (c) The University of Glasgow 2008
    -- License     :  see libraries/base/LICENSE
    --
    -- Maintainer  :  cvs-ghc@haskell.org
    -- Stability   :  internal
    -- Portability :  non-portable (GHC Extensions)
    --
    -- The IORef type
    --
    -----------------------------------------------------------------------------

    module GHC.IORef (
            IORef(..),
            newIORef, readIORef, writeIORef, atomicModifyIORef
        ) where

    import GHC.Base
    import GHC.STRef
    import GHC.IO
    import Data.Typeable.Internal( Typeable )

    -- ---------------------------------------------------------------------------
    -- IORefs

    -- |A mutable variable in the 'IO' monad
    newtype IORef a = IORef (STRef RealWorld a) deriving( Typeable )

    -- explicit instance because Haddock can't figure out a derived one
    instance Eq (IORef a) where
      IORef x == IORef y = x == y

    -- |Build a new 'IORef'
    newIORef    :: a -> IO (IORef a)
    newIORef v = stToIO (newSTRef v) >>= \ var -> return (IORef var)

    -- |Read the value of an 'IORef'
    readIORef   :: IORef a -> IO a
    readIORef  (IORef var) = stToIO (readSTRef var)

    -- |Write a new value into an 'IORef'
    writeIORef  :: IORef a -> a -> IO ()
    writeIORef (IORef var) v = stToIO (writeSTRef var v)

    atomicModifyIORef :: IORef a -> (a -> (a,b)) -> IO b
    atomicModifyIORef (IORef (STRef r#)) f = IO $ \s -> atomicModifyMutVar# r# f s