    -- |This module provides classes and instances for mutable state
    -- references.  Various implementation exist in common usage, but
    -- no way (until now ;-) to define functions using state references
    -- which don't depend on the specific monad or reference type in use.
    --
    -- These modules use several language extensions, including multi-parameter
    -- type classes and functional dependencies.
    module Data.StateRef
        ( module Data.StateRef
        , module Data.StateRef.Types
        , module Data.StateRef.Instances
        , module Data.Accessor
        ) where

    import Data.StateRef.Types
    import Data.StateRef.Instances
    import Data.Accessor

    -- |Read a 'Ref'.  See 'readReference'.
    readRef :: Ref m a -> m a
    readRef :: forall (m :: * -> *) a. Ref m a -> m a
    readRef = Ref m a -> m a
    forall sr (m :: * -> *) a. ReadRef sr m a => sr -> m a
    readReference

    -- |Write a 'Ref'.  See 'writeReference'
    writeRef :: Ref m a -> a -> m ()
    writeRef :: forall (m :: * -> *) a. Ref m a -> a -> m ()
    writeRef = Ref m a -> a -> m ()
    forall sr (m :: * -> *) a. WriteRef sr m a => sr -> a -> m ()
    writeReference

    -- |Modify a 'Ref'.  See 'modifyReference'.
    atomicModifyRef :: Ref m a -> (a -> (a,b)) -> m b
    atomicModifyRef :: forall (m :: * -> *) a b. Ref m a -> (a -> (a, b)) -> m b
    atomicModifyRef = Ref m a -> (a -> (a, b)) -> m b
    forall b. Ref m a -> (a -> (a, b)) -> m b
    forall sr (m :: * -> *) a b.
    ModifyRef sr m a =>
    sr -> (a -> (a, b)) -> m b
    atomicModifyReference

    -- |Modify a 'Ref'.  See 'modifyReference'.
    modifyRef :: Ref m a -> (a -> a) -> m ()
    modifyRef :: forall (m :: * -> *) a. Ref m a -> (a -> a) -> m ()
    modifyRef = Ref m a -> (a -> a) -> m ()
    forall sr (m :: * -> *) a.
    ModifyRef sr m a =>
    sr -> (a -> a) -> m ()
    modifyReference

    -- |Essentially the same concept as 'Control.Monad.State.gets',
    -- 'Control.Monad.State.asks', et al. Typically useful to read a field of
    -- a referenced ADT by passing a record selector as the second argument.
    readsRef :: (ReadRef sr m a,
                 Monad m) =>
                sr -> (a -> b) -> m b
    readsRef :: forall sr (m :: * -> *) a b.
    (ReadRef sr m a, Monad m) =>
    sr -> (a -> b) -> m b
    readsRef sr
    r a -> b
    f = do
        x <- sr -> m a
    forall sr (m :: * -> *) a. ReadRef sr m a => sr -> m a
    readReference sr
    r
        return (f x)

    -- |Construct a counter - a monadic value which, each time it is
    -- evaluated, returns the 'succ' of the previous value returned.
    newCounter :: (HasRef m, Monad m, Enum a) => a -> m (m a)
    newCounter :: forall (m :: * -> *) a. (HasRef m, Monad m, Enum a) => a -> m (m a)
    newCounter a
    n = do
        c <- a -> m (Ref m a)
    forall a. a -> m (Ref m a)
    forall (m :: * -> *) a. HasRef m => a -> m (Ref m a)
    newRef a
    n
        return $ do
            x <- readRef c
            writeRef c (succ x)
            return x

    -- |Create a \"lapse reader\" (suggestions for better terminology are more
    -- than welcome), a sort of a time-lapse of the variable.  The first
    -- motivating instance for this operation was a clock in a simple simulation
    -- application.  Given a 'TVar' 'Double' called \"clock\", a useful
    -- value \"dT\" is yielded by the expression: 'mkLapseReader' clock (-)
    mkLapseReader
      :: (ReadRef sr m a, HasRef m, Monad m) =>
         sr -> (a -> a -> b) -> m (m b)
    mkLapseReader :: forall sr (m :: * -> *) a b.
    (ReadRef sr m a, HasRef m, Monad m) =>
    sr -> (a -> a -> b) -> m (m b)
    mkLapseReader sr
    var a -> a -> b
    f = do
        startVal <- sr -> m a
    forall sr (m :: * -> *) a. ReadRef sr m a => sr -> m a
    readReference sr
    var
        prevRef <- newRef startVal

        return $ do
            newVal <- readReference var
            prevVal <- readRef prevRef

            writeReference prevRef newVal

            return (f newVal prevVal)