module System.Console.Haskeline.Monads(
MonadTrans(..),
MonadIO(..),
ReaderT,
runReaderT,
runReaderT',
mapReaderT,
asks,
StateT,
runStateT,
evalStateT',
mapStateT,
gets,
modify,
update,
MonadReader(..),
MonadState(..),
MaybeT(MaybeT),
runMaybeT,
orElse
) where
import Control.Monad (liftM)
import Control.Monad.Catch ()
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Class (MonadTrans(..))
import Control.Monad.Trans.Maybe (MaybeT(MaybeT),runMaybeT)
import Control.Monad.Trans.Reader hiding (ask,asks)
import qualified Control.Monad.Trans.Reader as Reader
import Control.Monad.Trans.State.Strict hiding (get, put, gets, modify)
import qualified Control.Monad.Trans.State.Strict as State
import Data.IORef
class Monad m => MonadReader r m where
ask :: m r
instance Monad m => MonadReader r (ReaderT r m) where
ask = Reader.ask
instance Monad m => MonadReader s (StateT s m) where
ask = get
instance {-# OVERLAPPABLE #-} (MonadReader r m, MonadTrans t, Monad (t m))
=> MonadReader r (t m) where
ask = lift ask
asks :: MonadReader r m => (r -> a) -> m a
asks f = liftM f ask
class Monad m => MonadState s m where
get :: m s
put :: s -> m ()
gets :: MonadState s m => (s -> a) -> m a
gets f = liftM f get
modify :: MonadState s m => (s -> s) -> m ()
modify f = get >>= put . f
update :: MonadState s m => (s -> (a,s)) -> m a
update f = do
s <- get
let (x,s') = f s
put s'
return x
runReaderT' :: r -> ReaderT r m a -> m a
runReaderT' = flip runReaderT
instance Monad m => MonadState s (StateT s m) where
get = State.get
put x = State.put $! x
instance {-# OVERLAPPABLE #-} (MonadState s m, MonadTrans t, Monad (t m))
=> MonadState s (t m) where
get = lift get
put = lift . put
instance MonadIO m => MonadState s (ReaderT (IORef s) m) where
get = ask >>= liftIO . readIORef
put s = ask >>= liftIO . flip writeIORef s
evalStateT' :: Monad m => s -> StateT s m a -> m a
evalStateT' s f = liftM fst $ runStateT f s
orElse :: Monad m => MaybeT m a -> m a -> m a
orElse (MaybeT f) g = f >>= maybe g return