    {- |
    Module      :  Control.Monad.Trans.Memo.StateCache
    Copyright   :  (c) Eduard Sergeev 2013
    License     :  BSD-style (see the file LICENSE)

    Maintainer  :  eduard.sergeev@gmail.com
    Stability   :  experimental
    Portability :  non-portable (multi-param classes, flexible instances)

    Generic StateCache - wrapper around `Control.Monad.Trans.State.Strict.StateT`

    -}

    {-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies,
      MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}

    module Control.Monad.Trans.Memo.StateCache
    (
        StateCache,
        runStateCache,
        container,
        setContainer,
        evalStateCache
    ) where

    import Control.Monad.Primitive
    import Control.Monad.ST
    import Data.Array.MArray
    import Data.Function
    import Control.Applicative
    import Control.Monad
    import Control.Monad.IO.Class
    import Control.Monad.Fix
    import Control.Monad.Trans.Class
    import Control.Monad.Trans.State.Strict
    import Data.Array.Base
    import Data.Array.IO
    import Data.Array.ST

    newtype StateCache c m a = StateCache { forall c (m :: * -> *) a. StateCache c m a -> StateT c m a
    toStateT :: StateT c m a }
        deriving ((forall a b. (a -> b) -> StateCache c m a -> StateCache c m b)
    -> (forall a b. a -> StateCache c m b -> StateCache c m a)
    -> Functor (StateCache c m)
    forall a b. a -> StateCache c m b -> StateCache c m a
    forall a b. (a -> b) -> StateCache c m a -> StateCache c m b
    forall c (m :: * -> *) a b.
    Functor m =>
    a -> StateCache c m b -> StateCache c m a
    forall c (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> StateCache c m a -> StateCache c m b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall c (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> StateCache c m a -> StateCache c m b
    fmap :: forall a b. (a -> b) -> StateCache c m a -> StateCache c m b
    $c<$ :: forall c (m :: * -> *) a b.
    Functor m =>
    a -> StateCache c m b -> StateCache c m a
    <$ :: forall a b. a -> StateCache c m b -> StateCache c m a
    Functor, Functor (StateCache c m)
    Functor (StateCache c m) =>
    (forall a. a -> StateCache c m a)
    -> (forall a b.
        StateCache c m (a -> b) -> StateCache c m a -> StateCache c m b)
    -> (forall a b c.
        (a -> b -> c)
        -> StateCache c m a -> StateCache c m b -> StateCache c m c)
    -> (forall a b.
        StateCache c m a -> StateCache c m b -> StateCache c m b)
    -> (forall a b.
        StateCache c m a -> StateCache c m b -> StateCache c m a)
    -> Applicative (StateCache c m)
    forall a. a -> StateCache c m a
    forall a b.
    StateCache c m a -> StateCache c m b -> StateCache c m a
    forall a b.
    StateCache c m a -> StateCache c m b -> StateCache c m b
    forall a b.
    StateCache c m (a -> b) -> StateCache c m a -> StateCache c m b
    forall a b c.
    (a -> b -> c)
    -> StateCache c m a -> StateCache c m b -> StateCache c m c
    forall c (m :: * -> *). Monad m => Functor (StateCache c m)
    forall c (m :: * -> *) a. Monad m => a -> StateCache c m a
    forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> StateCache c m b -> StateCache c m a
    forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> StateCache c m b -> StateCache c m b
    forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m (a -> b) -> StateCache c m a -> StateCache c m b
    forall c (m :: * -> *) a b c.
    Monad m =>
    (a -> b -> c)
    -> StateCache c m a -> StateCache c m b -> StateCache c m c
    forall (f :: * -> *).
    Functor f =>
    (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    $cpure :: forall c (m :: * -> *) a. Monad m => a -> StateCache c m a
    pure :: forall a. a -> StateCache c m a
    $c<*> :: forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m (a -> b) -> StateCache c m a -> StateCache c m b
    <*> :: forall a b.
    StateCache c m (a -> b) -> StateCache c m a -> StateCache c m b
    $cliftA2 :: forall c (m :: * -> *) a b c.
    Monad m =>
    (a -> b -> c)
    -> StateCache c m a -> StateCache c m b -> StateCache c m c
    liftA2 :: forall a b c.
    (a -> b -> c)
    -> StateCache c m a -> StateCache c m b -> StateCache c m c
    $c*> :: forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> StateCache c m b -> StateCache c m b
    *> :: forall a b.
    StateCache c m a -> StateCache c m b -> StateCache c m b
    $c<* :: forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> StateCache c m b -> StateCache c m a
    <* :: forall a b.
    StateCache c m a -> StateCache c m b -> StateCache c m a
    Applicative, Applicative (StateCache c m)
    Applicative (StateCache c m) =>
    (forall a. StateCache c m a)
    -> (forall a.
        StateCache c m a -> StateCache c m a -> StateCache c m a)
    -> (forall a. StateCache c m a -> StateCache c m [a])
    -> (forall a. StateCache c m a -> StateCache c m [a])
    -> Alternative (StateCache c m)
    forall a. StateCache c m a
    forall a. StateCache c m a -> StateCache c m [a]
    forall a. StateCache c m a -> StateCache c m a -> StateCache c m a
    forall c (m :: * -> *). MonadPlus m => Applicative (StateCache c m)
    forall c (m :: * -> *) a. MonadPlus m => StateCache c m a
    forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m [a]
    forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m a -> StateCache c m a
    forall (f :: * -> *).
    Applicative f =>
    (forall a. f a)
    -> (forall a. f a -> f a -> f a)
    -> (forall a. f a -> f [a])
    -> (forall a. f a -> f [a])
    -> Alternative f
    $cempty :: forall c (m :: * -> *) a. MonadPlus m => StateCache c m a
    empty :: forall a. StateCache c m a
    $c<|> :: forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m a -> StateCache c m a
    <|> :: forall a. StateCache c m a -> StateCache c m a -> StateCache c m a
    $csome :: forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m [a]
    some :: forall a. StateCache c m a -> StateCache c m [a]
    $cmany :: forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m [a]
    many :: forall a. StateCache c m a -> StateCache c m [a]
    Alternative, Applicative (StateCache c m)
    Applicative (StateCache c m) =>
    (forall a b.
     StateCache c m a -> (a -> StateCache c m b) -> StateCache c m b)
    -> (forall a b.
        StateCache c m a -> StateCache c m b -> StateCache c m b)
    -> (forall a. a -> StateCache c m a)
    -> Monad (StateCache c m)
    forall a. a -> StateCache c m a
    forall a b.
    StateCache c m a -> StateCache c m b -> StateCache c m b
    forall a b.
    StateCache c m a -> (a -> StateCache c m b) -> StateCache c m b
    forall c (m :: * -> *). Monad m => Applicative (StateCache c m)
    forall c (m :: * -> *) a. Monad m => a -> StateCache c m a
    forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> StateCache c m b -> StateCache c m b
    forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> (a -> StateCache c m b) -> StateCache c m b
    forall (m :: * -> *).
    Applicative m =>
    (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> (a -> StateCache c m b) -> StateCache c m b
    >>= :: forall a b.
    StateCache c m a -> (a -> StateCache c m b) -> StateCache c m b
    $c>> :: forall c (m :: * -> *) a b.
    Monad m =>
    StateCache c m a -> StateCache c m b -> StateCache c m b
    >> :: forall a b.
    StateCache c m a -> StateCache c m b -> StateCache c m b
    $creturn :: forall c (m :: * -> *) a. Monad m => a -> StateCache c m a
    return :: forall a. a -> StateCache c m a
    Monad, Monad (StateCache c m)
    Alternative (StateCache c m)
    (Alternative (StateCache c m), Monad (StateCache c m)) =>
    (forall a. StateCache c m a)
    -> (forall a.
        StateCache c m a -> StateCache c m a -> StateCache c m a)
    -> MonadPlus (StateCache c m)
    forall a. StateCache c m a
    forall a. StateCache c m a -> StateCache c m a -> StateCache c m a
    forall c (m :: * -> *). MonadPlus m => Monad (StateCache c m)
    forall c (m :: * -> *). MonadPlus m => Alternative (StateCache c m)
    forall c (m :: * -> *) a. MonadPlus m => StateCache c m a
    forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m a -> StateCache c m a
    forall (m :: * -> *).
    (Alternative m, Monad m) =>
    (forall a. m a) -> (forall a. m a -> m a -> m a) -> MonadPlus m
    $cmzero :: forall c (m :: * -> *) a. MonadPlus m => StateCache c m a
    mzero :: forall a. StateCache c m a
    $cmplus :: forall c (m :: * -> *) a.
    MonadPlus m =>
    StateCache c m a -> StateCache c m a -> StateCache c m a
    mplus :: forall a. StateCache c m a -> StateCache c m a -> StateCache c m a
    MonadPlus, Monad (StateCache c m)
    Monad (StateCache c m) =>
    (forall a. (a -> StateCache c m a) -> StateCache c m a)
    -> MonadFix (StateCache c m)
    forall a. (a -> StateCache c m a) -> StateCache c m a
    forall c (m :: * -> *). MonadFix m => Monad (StateCache c m)
    forall c (m :: * -> *) a.
    MonadFix m =>
    (a -> StateCache c m a) -> StateCache c m a
    forall (m :: * -> *).
    Monad m =>
    (forall a. (a -> m a) -> m a) -> MonadFix m
    $cmfix :: forall c (m :: * -> *) a.
    MonadFix m =>
    (a -> StateCache c m a) -> StateCache c m a
    mfix :: forall a. (a -> StateCache c m a) -> StateCache c m a
    MonadFix, (forall (m :: * -> *). Monad m => Monad (StateCache c m)) =>
    (forall (m :: * -> *) a. Monad m => m a -> StateCache c m a)
    -> MonadTrans (StateCache c)
    forall c (m :: * -> *). Monad m => Monad (StateCache c m)
    forall c (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (m :: * -> *). Monad m => Monad (StateCache c m)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *).
    (forall (m :: * -> *). Monad m => Monad (t m)) =>
    (forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
    $clift :: forall c (m :: * -> *) a. Monad m => m a -> StateCache c m a
    lift :: forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    MonadTrans, Monad (StateCache c m)
    Monad (StateCache c m) =>
    (forall a. IO a -> StateCache c m a) -> MonadIO (StateCache c m)
    forall a. IO a -> StateCache c m a
    forall c (m :: * -> *). MonadIO m => Monad (StateCache c m)
    forall c (m :: * -> *) a. MonadIO m => IO a -> StateCache c m a
    forall (m :: * -> *).
    Monad m =>
    (forall a. IO a -> m a) -> MonadIO m
    $cliftIO :: forall c (m :: * -> *) a. MonadIO m => IO a -> StateCache c m a
    liftIO :: forall a. IO a -> StateCache c m a
    MonadIO)

    {-# INLINE runStateCache #-}
    runStateCache :: StateCache s m a -> s -> m (a, s)
    runStateCache :: forall s (m :: * -> *) a. StateCache s m a -> s -> m (a, s)
    runStateCache = StateT s m a -> s -> m (a, s)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    runStateT (StateT s m a -> s -> m (a, s))
    -> (StateCache s m a -> StateT s m a)
    -> StateCache s m a
    -> s
    -> m (a, s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StateCache s m a -> StateT s m a
    forall c (m :: * -> *) a. StateCache c m a -> StateT c m a
    toStateT

    -- | Evaluates computation discarding the resulting container
    evalStateCache :: Monad m => StateCache c m a -> c -> m a
    {-# INLINE evalStateCache #-}
    evalStateCache :: forall (m :: * -> *) c a. Monad m => StateCache c m a -> c -> m a
    evalStateCache = StateT c m a -> c -> m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (StateT c m a -> c -> m a)
    -> (StateCache c m a -> StateT c m a)
    -> StateCache c m a
    -> c
    -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StateCache c m a -> StateT c m a
    forall c (m :: * -> *) a. StateCache c m a -> StateT c m a
    toStateT

    -- | Returns internal container
    container :: Monad m => StateCache c m c
    {-# INLINE container #-}
    container :: forall (m :: * -> *) c. Monad m => StateCache c m c
    container = StateT c m c -> StateCache c m c
    forall c (m :: * -> *) a. StateT c m a -> StateCache c m a
    StateCache StateT c m c
    forall (m :: * -> *) s. Monad m => StateT s m s
    get

    -- | Assigns new value to internal container
    setContainer :: Monad m => c -> StateCache c m ()
    {-# INLINE setContainer #-}
    setContainer :: forall (m :: * -> *) c. Monad m => c -> StateCache c m ()
    setContainer = StateT c m () -> StateCache c m ()
    forall c (m :: * -> *) a. StateT c m a -> StateCache c m a
    StateCache (StateT c m () -> StateCache c m ())
    -> (c -> StateT c m ()) -> c -> StateCache c m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . c -> StateT c m ()
    forall (m :: * -> *) s. Monad m => s -> StateT s m ()
    put

    instance PrimMonad m => PrimMonad (StateCache c m) where
      type PrimState (StateCache c m) = PrimState m
      primitive :: forall a.
    (State# (PrimState (StateCache c m))
     -> (# State# (PrimState (StateCache c m)), a #))
    -> StateCache c m a
    primitive = m a -> StateCache c m a
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> StateCache c m a)
    -> ((State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a)
    -> (State# (PrimState m) -> (# State# (PrimState m), a #))
    -> StateCache c m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    forall a.
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    forall (m :: * -> *) a.
    PrimMonad m =>
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    primitive

    instance MArray IOArray e (StateCache c IO) where
      getBounds :: forall i. Ix i => IOArray i e -> StateCache c IO (i, i)
    getBounds = IO (i, i) -> StateCache c IO (i, i)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (i, i) -> StateCache c IO (i, i))
    -> (IOArray i e -> IO (i, i))
    -> IOArray i e
    -> StateCache c IO (i, i)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOArray i e -> IO (i, i)
    forall i. Ix i => IOArray i e -> IO (i, i)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m (i, i)
    getBounds
      getNumElements :: forall i. Ix i => IOArray i e -> StateCache c IO Int
    getNumElements = IO Int -> StateCache c IO Int
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO Int -> StateCache c IO Int)
    -> (IOArray i e -> IO Int) -> IOArray i e -> StateCache c IO Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOArray i e -> IO Int
    forall i. Ix i => IOArray i e -> IO Int
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m Int
    getNumElements
      newArray :: forall i. Ix i => (i, i) -> e -> StateCache c IO (IOArray i e)
    newArray (i, i)
    a = IO (IOArray i e) -> StateCache c IO (IOArray i e)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (IOArray i e) -> StateCache c IO (IOArray i e))
    -> (e -> IO (IOArray i e)) -> e -> StateCache c IO (IOArray i e)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i, i) -> e -> IO (IOArray i e)
    forall i. Ix i => (i, i) -> e -> IO (IOArray i e)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    (i, i) -> e -> m (a i e)
    newArray (i, i)
    a
      unsafeRead :: forall i. Ix i => IOArray i e -> Int -> StateCache c IO e
    unsafeRead IOArray i e
    a = IO e -> StateCache c IO e
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO e -> StateCache c IO e)
    -> (Int -> IO e) -> Int -> StateCache c IO e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOArray i e -> Int -> IO e
    forall i. Ix i => IOArray i e -> Int -> IO e
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> m e
    unsafeRead IOArray i e
    a
      unsafeWrite :: forall i. Ix i => IOArray i e -> Int -> e -> StateCache c IO ()
    unsafeWrite IOArray i e
    a Int
    i = IO () -> StateCache c IO ()
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO () -> StateCache c IO ())
    -> (e -> IO ()) -> e -> StateCache c IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOArray i e -> Int -> e -> IO ()
    forall i. Ix i => IOArray i e -> Int -> e -> IO ()
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> e -> m ()
    unsafeWrite IOArray i e
    a Int
    i

    instance MArray IOUArray e IO => MArray IOUArray e (StateCache c IO) where
      getBounds :: forall i. Ix i => IOUArray i e -> StateCache c IO (i, i)
    getBounds = IO (i, i) -> StateCache c IO (i, i)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (i, i) -> StateCache c IO (i, i))
    -> (IOUArray i e -> IO (i, i))
    -> IOUArray i e
    -> StateCache c IO (i, i)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOUArray i e -> IO (i, i)
    forall i. Ix i => IOUArray i e -> IO (i, i)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m (i, i)
    getBounds
      getNumElements :: forall i. Ix i => IOUArray i e -> StateCache c IO Int
    getNumElements = IO Int -> StateCache c IO Int
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO Int -> StateCache c IO Int)
    -> (IOUArray i e -> IO Int) -> IOUArray i e -> StateCache c IO Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOUArray i e -> IO Int
    forall i. Ix i => IOUArray i e -> IO Int
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m Int
    getNumElements
      newArray :: forall i. Ix i => (i, i) -> e -> StateCache c IO (IOUArray i e)
    newArray (i, i)
    a = IO (IOUArray i e) -> StateCache c IO (IOUArray i e)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (IOUArray i e) -> StateCache c IO (IOUArray i e))
    -> (e -> IO (IOUArray i e)) -> e -> StateCache c IO (IOUArray i e)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i, i) -> e -> IO (IOUArray i e)
    forall i. Ix i => (i, i) -> e -> IO (IOUArray i e)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    (i, i) -> e -> m (a i e)
    newArray (i, i)
    a
      unsafeRead :: forall i. Ix i => IOUArray i e -> Int -> StateCache c IO e
    unsafeRead IOUArray i e
    a = IO e -> StateCache c IO e
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO e -> StateCache c IO e)
    -> (Int -> IO e) -> Int -> StateCache c IO e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOUArray i e -> Int -> IO e
    forall i. Ix i => IOUArray i e -> Int -> IO e
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> m e
    unsafeRead IOUArray i e
    a
      unsafeWrite :: forall i. Ix i => IOUArray i e -> Int -> e -> StateCache c IO ()
    unsafeWrite IOUArray i e
    a Int
    i = IO () -> StateCache c IO ()
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO () -> StateCache c IO ())
    -> (e -> IO ()) -> e -> StateCache c IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IOUArray i e -> Int -> e -> IO ()
    forall i. Ix i => IOUArray i e -> Int -> e -> IO ()
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> e -> m ()
    unsafeWrite IOUArray i e
    a Int
    i

    instance MArray (STArray s) e (StateCache c (ST s)) where
      getBounds :: forall i. Ix i => STArray s i e -> StateCache c (ST s) (i, i)
    getBounds = ST s (i, i) -> StateCache c (ST s) (i, i)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (i, i) -> StateCache c (ST s) (i, i))
    -> (STArray s i e -> ST s (i, i))
    -> STArray s i e
    -> StateCache c (ST s) (i, i)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STArray s i e -> ST s (i, i)
    forall i. Ix i => STArray s i e -> ST s (i, i)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m (i, i)
    getBounds
      getNumElements :: forall i. Ix i => STArray s i e -> StateCache c (ST s) Int
    getNumElements = ST s Int -> StateCache c (ST s) Int
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s Int -> StateCache c (ST s) Int)
    -> (STArray s i e -> ST s Int)
    -> STArray s i e
    -> StateCache c (ST s) Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STArray s i e -> ST s Int
    forall i. Ix i => STArray s i e -> ST s Int
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m Int
    getNumElements
      newArray :: forall i.
    Ix i =>
    (i, i) -> e -> StateCache c (ST s) (STArray s i e)
    newArray (i, i)
    a = ST s (STArray s i e) -> StateCache c (ST s) (STArray s i e)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (STArray s i e) -> StateCache c (ST s) (STArray s i e))
    -> (e -> ST s (STArray s i e))
    -> e
    -> StateCache c (ST s) (STArray s i e)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i, i) -> e -> ST s (STArray s i e)
    forall i. Ix i => (i, i) -> e -> ST s (STArray s i e)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    (i, i) -> e -> m (a i e)
    newArray (i, i)
    a
      unsafeRead :: forall i. Ix i => STArray s i e -> Int -> StateCache c (ST s) e
    unsafeRead STArray s i e
    a = ST s e -> StateCache c (ST s) e
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s e -> StateCache c (ST s) e)
    -> (Int -> ST s e) -> Int -> StateCache c (ST s) e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STArray s i e -> Int -> ST s e
    forall i. Ix i => STArray s i e -> Int -> ST s e
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> m e
    unsafeRead STArray s i e
    a
      unsafeWrite :: forall i.
    Ix i =>
    STArray s i e -> Int -> e -> StateCache c (ST s) ()
    unsafeWrite STArray s i e
    a Int
    i = ST s () -> StateCache c (ST s) ()
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s () -> StateCache c (ST s) ())
    -> (e -> ST s ()) -> e -> StateCache c (ST s) ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STArray s i e -> Int -> e -> ST s ()
    forall i. Ix i => STArray s i e -> Int -> e -> ST s ()
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> e -> m ()
    unsafeWrite STArray s i e
    a Int
    i

    instance MArray (STUArray s) e (ST s) => MArray (STUArray s) e (StateCache c (ST s)) where
      getBounds :: forall i. Ix i => STUArray s i e -> StateCache c (ST s) (i, i)
    getBounds = ST s (i, i) -> StateCache c (ST s) (i, i)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (i, i) -> StateCache c (ST s) (i, i))
    -> (STUArray s i e -> ST s (i, i))
    -> STUArray s i e
    -> StateCache c (ST s) (i, i)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STUArray s i e -> ST s (i, i)
    forall i. Ix i => STUArray s i e -> ST s (i, i)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m (i, i)
    getBounds
      getNumElements :: forall i. Ix i => STUArray s i e -> StateCache c (ST s) Int
    getNumElements = ST s Int -> StateCache c (ST s) Int
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s Int -> StateCache c (ST s) Int)
    -> (STUArray s i e -> ST s Int)
    -> STUArray s i e
    -> StateCache c (ST s) Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STUArray s i e -> ST s Int
    forall i. Ix i => STUArray s i e -> ST s Int
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> m Int
    getNumElements
      newArray :: forall i.
    Ix i =>
    (i, i) -> e -> StateCache c (ST s) (STUArray s i e)
    newArray (i, i)
    a = ST s (STUArray s i e) -> StateCache c (ST s) (STUArray s i e)
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (STUArray s i e) -> StateCache c (ST s) (STUArray s i e))
    -> (e -> ST s (STUArray s i e))
    -> e
    -> StateCache c (ST s) (STUArray s i e)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (i, i) -> e -> ST s (STUArray s i e)
    forall i. Ix i => (i, i) -> e -> ST s (STUArray s i e)
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    (i, i) -> e -> m (a i e)
    newArray (i, i)
    a
      unsafeRead :: forall i. Ix i => STUArray s i e -> Int -> StateCache c (ST s) e
    unsafeRead STUArray s i e
    a = ST s e -> StateCache c (ST s) e
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s e -> StateCache c (ST s) e)
    -> (Int -> ST s e) -> Int -> StateCache c (ST s) e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STUArray s i e -> Int -> ST s e
    forall i. Ix i => STUArray s i e -> Int -> ST s e
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> m e
    unsafeRead STUArray s i e
    a
      unsafeWrite :: forall i.
    Ix i =>
    STUArray s i e -> Int -> e -> StateCache c (ST s) ()
    unsafeWrite STUArray s i e
    a Int
    i = ST s () -> StateCache c (ST s) ()
    forall (m :: * -> *) a. Monad m => m a -> StateCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s () -> StateCache c (ST s) ())
    -> (e -> ST s ()) -> e -> StateCache c (ST s) ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STUArray s i e -> Int -> e -> ST s ()
    forall i. Ix i => STUArray s i e -> Int -> e -> ST s ()
    forall (a :: * -> * -> *) e (m :: * -> *) i.
    (MArray a e m, Ix i) =>
    a i e -> Int -> e -> m ()
    unsafeWrite STUArray s i e
    a Int
    i