Changing Reader environment type (in an effect system?)
Haskell Community [Unofficial]
May 29, 2026
I got the idea for something like this but I don’t know how practical it is
class (MonadReader r m, forall r' . MonadReader r' (ChangeReader m r')) => SmartMonadReader r m where
data family ChangeReader m r' :: Type -> Type
changeReader :: (r' -> r) -> m a -> ChangeReader m r' a
instance Monad m => SmartMonadReader r (ReaderT r m) where
newtype instance ChangeReader (ReaderT r m) r' a = ChangeReaderReaderT (ReaderT r' m a)
deriving newtype (Functor, Applicative, Monad, MonadReader r')
changeReader f x = ChangeReaderReaderT (withReaderT f x)
instance (SmartMonadReader r m) => SmartMonadReader r (MaybeT m) where
newtype instance ChangeReader (MaybeT m) r' a = ChangeReaderMaybeT (MaybeT (ChangeReader m r') a)
changeReader f x = ChangeReaderMaybeT (mapMaybeT (changeReader f) x)
deriving newtype instance (SmartMonadReader r m) => Functor (ChangeReader (MaybeT m) r')
deriving newtype instance (SmartMonadReader r m) => Applicative (ChangeReader (MaybeT m) r')
deriving newtype instance (SmartMonadReader r m) => Monad (ChangeReader (MaybeT m) r')
deriving newtype instance (SmartMonadReader r m) => MonadReader r' (ChangeReader (MaybeT m) r')
instance (Monoid w, SmartMonadReader r m) => SmartMonadReader r (WriterT w m) where
newtype instance ChangeReader (WriterT w m) r' a = ChangeReaderWriterT (WriterT w (ChangeReader m r') a)
changeReader f x = ChangeReaderWriterT (mapWriterT (changeReader f) x)
deriving newtype instance (Monoid w, SmartMonadReader r m) => Functor (ChangeReader (WriterT w m) r')
deriving newtype instance (Monoid w, SmartMonadReader r m) => Applicative (ChangeReader (WriterT w m) r')
deriving newtype instance (Monoid w, SmartMonadReader r m) => Monad (ChangeReader (WriterT w m) r')
deriving newtype instance (Monoid w, SmartMonadReader r m) => MonadReader r' (ChangeReader (WriterT w m) r')
Discussion in the ATmosphere