module Control.Monad.Trans.Memo.ReaderCache
(
ReaderCache(..),
container
) where
import Data.Function
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Control.Monad.Trans
newtype ReaderCache c m a = ReaderCache { evalReaderCache :: c -> m a }
container :: Monad m => ReaderCache c m c
container = ReaderCache $ \ !c -> return c
instance (Functor m) => Functor (ReaderCache c m) where
fmap f m = ReaderCache $ \ !c -> fmap f (evalReaderCache m c)
instance (Applicative m) => Applicative (ReaderCache arr m) where
pure a = ReaderCache $ \_ -> pure a
f <*> v = ReaderCache $ \ !c -> evalReaderCache f c <*> evalReaderCache v c
instance (Alternative m) => Alternative (ReaderCache c m) where
empty = ReaderCache $ const empty
m <|> n = ReaderCache $ \ !c -> evalReaderCache m c <|> evalReaderCache n c
instance (Monad m) => Monad (ReaderCache c m) where
return a = ReaderCache $ \ !c -> return a
m >>= k = ReaderCache $ \ !c -> do
a <- evalReaderCache m c
evalReaderCache (k a) c
m >> k = ReaderCache $ \ !c -> do
evalReaderCache m c
evalReaderCache k c
instance (MonadPlus m) => MonadPlus (ReaderCache c m) where
mzero = lift mzero
m `mplus` n = ReaderCache $ \ !c -> evalReaderCache m c `mplus` evalReaderCache n c
instance (MonadFix m) => MonadFix (ReaderCache c m) where
mfix f = ReaderCache $ \ !c -> mfix $ \a -> evalReaderCache (f a) c
instance MonadTrans (ReaderCache c) where
lift = ReaderCache . const
instance (MonadIO m) => MonadIO (ReaderCache c m) where
liftIO = lift . liftIO