rio-0.1.0.0: src/RIO/Prelude/RIO.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module RIO.Prelude.RIO
( RIO (..)
, runRIO
, liftRIO
) where
import RIO.Prelude.Reexports
-- | The Reader+IO monad. This is different from a 'ReaderT' because:
--
-- * It's not a transformer, it hardcodes IO for simpler usage and
-- error messages.
--
-- * Instances of typeclasses like 'MonadLogger' are implemented using
-- classes defined on the environment, instead of using an
-- underlying monad.
newtype RIO env a = RIO { unRIO :: ReaderT env IO a }
deriving (Functor,Applicative,Monad,MonadIO,MonadReader env,MonadThrow)
runRIO :: MonadIO m => env -> RIO env a -> m a
runRIO env (RIO (ReaderT f)) = liftIO (f env)
liftRIO :: (MonadIO m, MonadReader env m) => RIO env a -> m a
liftRIO rio = do
env <- ask
runRIO env rio
instance MonadUnliftIO (RIO env) where
askUnliftIO = RIO $ ReaderT $ \r ->
withUnliftIO $ \u ->
return (UnliftIO (unliftIO u . flip runReaderT r . unRIO))
instance PrimMonad (RIO env) where
type PrimState (RIO env) = PrimState IO
primitive = RIO . ReaderT . const . primitive