module Control.Monad.Array.MArray (MArrayM, liftMArray, evalMArrayM, execMArrayM, evalMArrayM_, execMArrayM_) where
import Control.Monad.Array.Class
import Control.Monad.ST.Class
import GHC.Arr
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Trans
import Data.Array.Base
import Control.Monad
newtype MArrayM a e m x = MArrayM {runMArrayM :: ReaderT e (StateT (a Int e) m) x} deriving (Monad, MonadFix, MonadPlus, MonadIO, MonadST)
evalMArrayM :: (Monad m, MArray a e m) => Int -> e -> MArrayM a e m x -> m x
evalMArrayM n d m = newArray (0, n1) d >>= evalStateT (runReaderT (runMArrayM m) d)
execMArrayM :: (Monad m, MArray a e m) => Int -> e -> MArrayM a e m x -> m (a Int e)
execMArrayM n d m = newArray (0, n1) d >>= execStateT (runReaderT (runMArrayM m) d)
evalMArrayM_ :: (Monad m, MArray a e m) => Int -> MArrayM a e m x -> m x
evalMArrayM_ n = evalMArrayM n emptyElement
execMArrayM_ :: (Monad m, MArray a e m) => Int -> MArrayM a e m x -> m (a Int e)
execMArrayM_ n = execMArrayM n emptyElement
emptyElement :: e
emptyElement = error "Undefined array element"
instance (Monad m, MArray a e m) => MonadArray (MArrayM a e m) where
type ArrayElem (MArrayM a e m) = e
unsafeWriteAt i x = MArrayM $ do arr <- get
lift2 $ unsafeWrite arr i x
unsafeReadAt i = MArrayM $ do arr <- get
lift2 $ unsafeRead arr i
askSize = MArrayM (get >>= lift2 . liftM rangeSize . getBounds)
resize n = do prevSize <- askSize
prevConts <- mapM unsafeReadAt [0..prevSize1]
def <- MArrayM ask
arr' <- liftMArray $ newListArray (0, n1) (prevConts ++ replicate (n prevSize) def)
MArrayM $ put arr'
askElems = MArrayM $ get >>= lift2 . getElems
askAssocs = MArrayM $ get >>= lift2 . getAssocs
liftMArray :: (Monad m, MArray a e m) => m x -> MArrayM a e m x
liftMArray = MArrayM . lift2
lift2 :: (MonadTrans t1, MonadTrans t2, Monad m, Monad (t2 m)) => m a -> t1 (t2 m) a
lift2 = lift . lift