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

    Maintainer  :  eduard.sergeev@gmail.com
    Stability   :  experimental
    Portability :  non-portable

    Generic StateCache - wrapper around `Control.Monad.Trans.Reader.ReaderT`

    -}

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

    module Control.Monad.Trans.Memo.ReaderCache
    (

      ReaderCache,
      evalReaderCache,
      container

    ) where

    import Control.Applicative
    import Control.Monad
    import Control.Monad.IO.Class
    import Control.Monad.Fix
    import Control.Monad.Primitive
    import Control.Monad.ST
    import Control.Monad.Trans.Class
    import Control.Monad.Trans.Reader
    import Data.Array.Base
    import Data.Array.IO
    import Data.Array.ST

    newtype ReaderCache c m a = ReaderCache { forall c (m :: * -> *) a. ReaderCache c m a -> ReaderT c m a
    toReaderT :: ReaderT c m a }
        deriving ((forall a b. (a -> b) -> ReaderCache c m a -> ReaderCache c m b)
    -> (forall a b. a -> ReaderCache c m b -> ReaderCache c m a)
    -> Functor (ReaderCache c m)
    forall a b. a -> ReaderCache c m b -> ReaderCache c m a
    forall a b. (a -> b) -> ReaderCache c m a -> ReaderCache c m b
    forall c (m :: * -> *) a b.
    Functor m =>
    a -> ReaderCache c m b -> ReaderCache c m a
    forall c (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> ReaderCache c m a -> ReaderCache 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) -> ReaderCache c m a -> ReaderCache c m b
    fmap :: forall a b. (a -> b) -> ReaderCache c m a -> ReaderCache c m b
    $c<$ :: forall c (m :: * -> *) a b.
    Functor m =>
    a -> ReaderCache c m b -> ReaderCache c m a
    <$ :: forall a b. a -> ReaderCache c m b -> ReaderCache c m a
    Functor, Functor (ReaderCache c m)
    Functor (ReaderCache c m) =>
    (forall a. a -> ReaderCache c m a)
    -> (forall a b.
        ReaderCache c m (a -> b) -> ReaderCache c m a -> ReaderCache c m b)
    -> (forall a b c.
        (a -> b -> c)
        -> ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m c)
    -> (forall a b.
        ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b)
    -> (forall a b.
        ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m a)
    -> Applicative (ReaderCache c m)
    forall a. a -> ReaderCache c m a
    forall a b.
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m a
    forall a b.
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    forall a b.
    ReaderCache c m (a -> b) -> ReaderCache c m a -> ReaderCache c m b
    forall a b c.
    (a -> b -> c)
    -> ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m c
    forall c (m :: * -> *). Applicative m => Functor (ReaderCache c m)
    forall c (m :: * -> *) a. Applicative m => a -> ReaderCache c m a
    forall c (m :: * -> *) a b.
    Applicative m =>
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m a
    forall c (m :: * -> *) a b.
    Applicative m =>
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    forall c (m :: * -> *) a b.
    Applicative m =>
    ReaderCache c m (a -> b) -> ReaderCache c m a -> ReaderCache c m b
    forall c (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> c)
    -> ReaderCache c m a -> ReaderCache c m b -> ReaderCache 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. Applicative m => a -> ReaderCache c m a
    pure :: forall a. a -> ReaderCache c m a
    $c<*> :: forall c (m :: * -> *) a b.
    Applicative m =>
    ReaderCache c m (a -> b) -> ReaderCache c m a -> ReaderCache c m b
    <*> :: forall a b.
    ReaderCache c m (a -> b) -> ReaderCache c m a -> ReaderCache c m b
    $cliftA2 :: forall c (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> c)
    -> ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m c
    liftA2 :: forall a b c.
    (a -> b -> c)
    -> ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m c
    $c*> :: forall c (m :: * -> *) a b.
    Applicative m =>
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    *> :: forall a b.
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    $c<* :: forall c (m :: * -> *) a b.
    Applicative m =>
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m a
    <* :: forall a b.
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m a
    Applicative, Applicative (ReaderCache c m)
    Applicative (ReaderCache c m) =>
    (forall a. ReaderCache c m a)
    -> (forall a.
        ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a)
    -> (forall a. ReaderCache c m a -> ReaderCache c m [a])
    -> (forall a. ReaderCache c m a -> ReaderCache c m [a])
    -> Alternative (ReaderCache c m)
    forall a. ReaderCache c m a
    forall a. ReaderCache c m a -> ReaderCache c m [a]
    forall a.
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a
    forall c (m :: * -> *).
    Alternative m =>
    Applicative (ReaderCache c m)
    forall c (m :: * -> *) a. Alternative m => ReaderCache c m a
    forall c (m :: * -> *) a.
    Alternative m =>
    ReaderCache c m a -> ReaderCache c m [a]
    forall c (m :: * -> *) a.
    Alternative m =>
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache 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. Alternative m => ReaderCache c m a
    empty :: forall a. ReaderCache c m a
    $c<|> :: forall c (m :: * -> *) a.
    Alternative m =>
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a
    <|> :: forall a.
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a
    $csome :: forall c (m :: * -> *) a.
    Alternative m =>
    ReaderCache c m a -> ReaderCache c m [a]
    some :: forall a. ReaderCache c m a -> ReaderCache c m [a]
    $cmany :: forall c (m :: * -> *) a.
    Alternative m =>
    ReaderCache c m a -> ReaderCache c m [a]
    many :: forall a. ReaderCache c m a -> ReaderCache c m [a]
    Alternative, Applicative (ReaderCache c m)
    Applicative (ReaderCache c m) =>
    (forall a b.
     ReaderCache c m a -> (a -> ReaderCache c m b) -> ReaderCache c m b)
    -> (forall a b.
        ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b)
    -> (forall a. a -> ReaderCache c m a)
    -> Monad (ReaderCache c m)
    forall a. a -> ReaderCache c m a
    forall a b.
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    forall a b.
    ReaderCache c m a -> (a -> ReaderCache c m b) -> ReaderCache c m b
    forall c (m :: * -> *). Monad m => Applicative (ReaderCache c m)
    forall c (m :: * -> *) a. Monad m => a -> ReaderCache c m a
    forall c (m :: * -> *) a b.
    Monad m =>
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    forall c (m :: * -> *) a b.
    Monad m =>
    ReaderCache c m a -> (a -> ReaderCache c m b) -> ReaderCache 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 =>
    ReaderCache c m a -> (a -> ReaderCache c m b) -> ReaderCache c m b
    >>= :: forall a b.
    ReaderCache c m a -> (a -> ReaderCache c m b) -> ReaderCache c m b
    $c>> :: forall c (m :: * -> *) a b.
    Monad m =>
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    >> :: forall a b.
    ReaderCache c m a -> ReaderCache c m b -> ReaderCache c m b
    $creturn :: forall c (m :: * -> *) a. Monad m => a -> ReaderCache c m a
    return :: forall a. a -> ReaderCache c m a
    Monad, Monad (ReaderCache c m)
    Alternative (ReaderCache c m)
    (Alternative (ReaderCache c m), Monad (ReaderCache c m)) =>
    (forall a. ReaderCache c m a)
    -> (forall a.
        ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a)
    -> MonadPlus (ReaderCache c m)
    forall a. ReaderCache c m a
    forall a.
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a
    forall c (m :: * -> *). MonadPlus m => Monad (ReaderCache c m)
    forall c (m :: * -> *).
    MonadPlus m =>
    Alternative (ReaderCache c m)
    forall c (m :: * -> *) a. MonadPlus m => ReaderCache c m a
    forall c (m :: * -> *) a.
    MonadPlus m =>
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache 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 => ReaderCache c m a
    mzero :: forall a. ReaderCache c m a
    $cmplus :: forall c (m :: * -> *) a.
    MonadPlus m =>
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a
    mplus :: forall a.
    ReaderCache c m a -> ReaderCache c m a -> ReaderCache c m a
    MonadPlus, Monad (ReaderCache c m)
    Monad (ReaderCache c m) =>
    (forall a. (a -> ReaderCache c m a) -> ReaderCache c m a)
    -> MonadFix (ReaderCache c m)
    forall a. (a -> ReaderCache c m a) -> ReaderCache c m a
    forall c (m :: * -> *). MonadFix m => Monad (ReaderCache c m)
    forall c (m :: * -> *) a.
    MonadFix m =>
    (a -> ReaderCache c m a) -> ReaderCache c m a
    forall (m :: * -> *).
    Monad m =>
    (forall a. (a -> m a) -> m a) -> MonadFix m
    $cmfix :: forall c (m :: * -> *) a.
    MonadFix m =>
    (a -> ReaderCache c m a) -> ReaderCache c m a
    mfix :: forall a. (a -> ReaderCache c m a) -> ReaderCache c m a
    MonadFix, (forall (m :: * -> *). Monad m => Monad (ReaderCache c m)) =>
    (forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a)
    -> MonadTrans (ReaderCache c)
    forall c (m :: * -> *). Monad m => Monad (ReaderCache c m)
    forall c (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (m :: * -> *). Monad m => Monad (ReaderCache c m)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache 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 -> ReaderCache c m a
    lift :: forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    MonadTrans, Monad (ReaderCache c m)
    Monad (ReaderCache c m) =>
    (forall a. IO a -> ReaderCache c m a) -> MonadIO (ReaderCache c m)
    forall a. IO a -> ReaderCache c m a
    forall c (m :: * -> *). MonadIO m => Monad (ReaderCache c m)
    forall c (m :: * -> *) a. MonadIO m => IO a -> ReaderCache c m a
    forall (m :: * -> *).
    Monad m =>
    (forall a. IO a -> m a) -> MonadIO m
    $cliftIO :: forall c (m :: * -> *) a. MonadIO m => IO a -> ReaderCache c m a
    liftIO :: forall a. IO a -> ReaderCache c m a
    MonadIO)

    {-# INLINE evalReaderCache #-}
    evalReaderCache :: ReaderCache r m a -> r -> m a
    evalReaderCache :: forall r (m :: * -> *) a. ReaderCache r m a -> r -> m a
    evalReaderCache = ReaderT r m a -> r -> m a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT (ReaderT r m a -> r -> m a)
    -> (ReaderCache r m a -> ReaderT r m a)
    -> ReaderCache r m a
    -> r
    -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ReaderCache r m a -> ReaderT r m a
    forall c (m :: * -> *) a. ReaderCache c m a -> ReaderT c m a
    toReaderT

    -- | Returns internal container
    container :: Monad m => ReaderCache c m c
    {-# INLINE container #-}
    container :: forall (m :: * -> *) c. Monad m => ReaderCache c m c
    container = ReaderT c m c -> ReaderCache c m c
    forall c (m :: * -> *) a. ReaderT c m a -> ReaderCache c m a
    ReaderCache ReaderT c m c
    forall (m :: * -> *) r. Monad m => ReaderT r m r
    ask

    instance PrimMonad m => PrimMonad (ReaderCache c m) where
      type PrimState (ReaderCache c m) = PrimState m
      primitive :: forall a.
    (State# (PrimState (ReaderCache c m))
     -> (# State# (PrimState (ReaderCache c m)), a #))
    -> ReaderCache c m a
    primitive = m a -> ReaderCache c m a
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> ReaderCache c m a)
    -> ((State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a)
    -> (State# (PrimState m) -> (# State# (PrimState m), a #))
    -> ReaderCache 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 (ReaderCache c IO) where
      getBounds :: forall i. Ix i => IOArray i e -> ReaderCache c IO (i, i)
    getBounds = IO (i, i) -> ReaderCache c IO (i, i)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (i, i) -> ReaderCache c IO (i, i))
    -> (IOArray i e -> IO (i, i))
    -> IOArray i e
    -> ReaderCache 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 -> ReaderCache c IO Int
    getNumElements = IO Int -> ReaderCache c IO Int
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO Int -> ReaderCache c IO Int)
    -> (IOArray i e -> IO Int) -> IOArray i e -> ReaderCache 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 -> ReaderCache c IO (IOArray i e)
    newArray (i, i)
    a = IO (IOArray i e) -> ReaderCache c IO (IOArray i e)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (IOArray i e) -> ReaderCache c IO (IOArray i e))
    -> (e -> IO (IOArray i e)) -> e -> ReaderCache 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 -> ReaderCache c IO e
    unsafeRead IOArray i e
    a = IO e -> ReaderCache c IO e
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO e -> ReaderCache c IO e)
    -> (Int -> IO e) -> Int -> ReaderCache 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 -> ReaderCache c IO ()
    unsafeWrite IOArray i e
    a Int
    i = IO () -> ReaderCache c IO ()
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO () -> ReaderCache c IO ())
    -> (e -> IO ()) -> e -> ReaderCache 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 (ReaderCache c IO) where
      getBounds :: forall i. Ix i => IOUArray i e -> ReaderCache c IO (i, i)
    getBounds = IO (i, i) -> ReaderCache c IO (i, i)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (i, i) -> ReaderCache c IO (i, i))
    -> (IOUArray i e -> IO (i, i))
    -> IOUArray i e
    -> ReaderCache 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 -> ReaderCache c IO Int
    getNumElements = IO Int -> ReaderCache c IO Int
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO Int -> ReaderCache c IO Int)
    -> (IOUArray i e -> IO Int) -> IOUArray i e -> ReaderCache 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 -> ReaderCache c IO (IOUArray i e)
    newArray (i, i)
    a = IO (IOUArray i e) -> ReaderCache c IO (IOUArray i e)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO (IOUArray i e) -> ReaderCache c IO (IOUArray i e))
    -> (e -> IO (IOUArray i e)) -> e -> ReaderCache 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 -> ReaderCache c IO e
    unsafeRead IOUArray i e
    a = IO e -> ReaderCache c IO e
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO e -> ReaderCache c IO e)
    -> (Int -> IO e) -> Int -> ReaderCache 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 -> ReaderCache c IO ()
    unsafeWrite IOUArray i e
    a Int
    i = IO () -> ReaderCache c IO ()
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (IO () -> ReaderCache c IO ())
    -> (e -> IO ()) -> e -> ReaderCache 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 (ReaderCache c (ST s)) where
      getBounds :: forall i. Ix i => STArray s i e -> ReaderCache c (ST s) (i, i)
    getBounds = ST s (i, i) -> ReaderCache c (ST s) (i, i)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (i, i) -> ReaderCache c (ST s) (i, i))
    -> (STArray s i e -> ST s (i, i))
    -> STArray s i e
    -> ReaderCache 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 -> ReaderCache c (ST s) Int
    getNumElements = ST s Int -> ReaderCache c (ST s) Int
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s Int -> ReaderCache c (ST s) Int)
    -> (STArray s i e -> ST s Int)
    -> STArray s i e
    -> ReaderCache 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 -> ReaderCache c (ST s) (STArray s i e)
    newArray (i, i)
    a = ST s (STArray s i e) -> ReaderCache c (ST s) (STArray s i e)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (STArray s i e) -> ReaderCache c (ST s) (STArray s i e))
    -> (e -> ST s (STArray s i e))
    -> e
    -> ReaderCache 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 -> ReaderCache c (ST s) e
    unsafeRead STArray s i e
    a = ST s e -> ReaderCache c (ST s) e
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s e -> ReaderCache c (ST s) e)
    -> (Int -> ST s e) -> Int -> ReaderCache 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 -> ReaderCache c (ST s) ()
    unsafeWrite STArray s i e
    a Int
    i = ST s () -> ReaderCache c (ST s) ()
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s () -> ReaderCache c (ST s) ())
    -> (e -> ST s ()) -> e -> ReaderCache 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 (ReaderCache c (ST s)) where
      getBounds :: forall i. Ix i => STUArray s i e -> ReaderCache c (ST s) (i, i)
    getBounds = ST s (i, i) -> ReaderCache c (ST s) (i, i)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (i, i) -> ReaderCache c (ST s) (i, i))
    -> (STUArray s i e -> ST s (i, i))
    -> STUArray s i e
    -> ReaderCache 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 -> ReaderCache c (ST s) Int
    getNumElements = ST s Int -> ReaderCache c (ST s) Int
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s Int -> ReaderCache c (ST s) Int)
    -> (STUArray s i e -> ST s Int)
    -> STUArray s i e
    -> ReaderCache 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 -> ReaderCache c (ST s) (STUArray s i e)
    newArray (i, i)
    a = ST s (STUArray s i e) -> ReaderCache c (ST s) (STUArray s i e)
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s (STUArray s i e) -> ReaderCache c (ST s) (STUArray s i e))
    -> (e -> ST s (STUArray s i e))
    -> e
    -> ReaderCache 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 -> ReaderCache c (ST s) e
    unsafeRead STUArray s i e
    a = ST s e -> ReaderCache c (ST s) e
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s e -> ReaderCache c (ST s) e)
    -> (Int -> ST s e) -> Int -> ReaderCache 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 -> ReaderCache c (ST s) ()
    unsafeWrite STUArray s i e
    a Int
    i = ST s () -> ReaderCache c (ST s) ()
    forall (m :: * -> *) a. Monad m => m a -> ReaderCache c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (ST s () -> ReaderCache c (ST s) ())
    -> (e -> ST s ()) -> e -> ReaderCache 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