    {-# LANGUAGE Unsafe #-}
    {-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples #-}
    {-# OPTIONS_HADDOCK not-home #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.STRef
    -- Copyright   :  (c) The University of Glasgow, 1994-2002
    -- License     :  see libraries/base/LICENSE
    --
    -- Maintainer  :  cvs-ghc@haskell.org
    -- Stability   :  internal
    -- Portability :  non-portable (GHC Extensions)
    --
    -- References in the 'ST' monad.
    --
    -----------------------------------------------------------------------------

    module GHC.STRef (
            STRef(..),
            newSTRef, readSTRef, writeSTRef
        ) where

    import GHC.ST
    import GHC.Base

    -- $setup
    -- >>> import Prelude
    -- >>> import Control.Monad.ST

    data STRef s a = STRef (MutVar# s a)
    -- ^ a value of type @STRef s a@ is a mutable variable in state thread @s@,
    -- containing a value of type @a@
    --
    -- >>> :{
    -- runST (do
    --     ref <- newSTRef "hello"
    --     x <- readSTRef ref
    --     writeSTRef ref (x ++ "world")
    --     readSTRef ref )
    -- :}
    -- "helloworld"

    -- |Build a new 'STRef' in the current state thread
    newSTRef :: a -> ST s (STRef s a)
    newSTRef :: forall a s. a -> ST s (STRef s a)
    newSTRef a
    init = forall s a. STRep s a -> ST s a
    ST forall a b. (a -> b) -> a -> b
    $ \State# s
    s1# ->
        case forall a d. a -> State# d -> (# State# d, MutVar# d a #)
    newMutVar# a
    init State# s
    s1#            of { (# State# s
    s2#, MutVar# s a
    var# #) ->
        (# State# s
    s2#, forall s a. MutVar# s a -> STRef s a
    STRef MutVar# s a
    var# #) }

    -- |Read the value of an 'STRef'
    readSTRef :: STRef s a -> ST s a
    readSTRef :: forall s a. STRef s a -> ST s a
    readSTRef (STRef MutVar# s a
    var#) = forall s a. STRep s a -> ST s a
    ST forall a b. (a -> b) -> a -> b
    $ \State# s
    s1# -> forall d a. MutVar# d a -> State# d -> (# State# d, a #)
    readMutVar# MutVar# s a
    var# State# s
    s1#

    -- |Write a new value into an 'STRef'
    writeSTRef :: STRef s a -> a -> ST s ()
    writeSTRef :: forall s a. STRef s a -> a -> ST s ()
    writeSTRef (STRef MutVar# s a
    var#) a
    val = forall s a. STRep s a -> ST s a
    ST forall a b. (a -> b) -> a -> b
    $ \State# s
    s1# ->
        case forall d a. MutVar# d a -> a -> State# d -> State# d
    writeMutVar# MutVar# s a
    var# a
    val State# s
    s1#      of { State# s
    s2# ->
        (# State# s
    s2#, () #) }

    -- | Pointer equality.
    --
    -- @since 2.01
    instance Eq (STRef s a) where
        STRef MutVar# s a
    v1# == :: STRef s a -> STRef s a -> Bool
    == STRef MutVar# s a
    v2# = Int# -> Bool
    isTrue# (forall d a. MutVar# d a -> MutVar# d a -> Int#
    sameMutVar# MutVar# s a
    v1# MutVar# s a
    v2#)