    {-# 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 = STRep s (STRef s a) -> ST s (STRef s a)
    forall s a. STRep s a -> ST s a
    ST (STRep s (STRef s a) -> ST s (STRef s a))
    -> STRep s (STRef s a) -> ST s (STRef s a)
    forall a b. (a -> b) -> a -> b
    $ \State# s
    s1# ->
        case a -> State# s -> (# State# s, MutVar# s a #)
    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#, MutVar# s a -> STRef s a
    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#) = STRep s a -> ST s a
    forall s a. STRep s a -> ST s a
    ST (STRep s a -> ST s a) -> STRep s a -> ST s a
    forall a b. (a -> b) -> a -> b
    $ \State# s
    s1# -> MutVar# s a -> STRep s a
    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 = STRep s () -> ST s ()
    forall s a. STRep s a -> ST s a
    ST (STRep s () -> ST s ()) -> STRep s () -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ \State# s
    s1# ->
        case MutVar# s a -> a -> State# s -> State# s
    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# (MutVar# s a -> MutVar# s a -> Int#
    forall s a. MutVar# s a -> MutVar# s a -> Int#
    sameMutVar# MutVar# s a
    v1# MutVar# s a
    v2#)