{-# 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