Created
July 2, 2019 15:28
-
-
Save dmwit/ce531720746377e683385341071d0318 to your computer and use it in GitHub Desktop.
With MonadReader (and other mtl classes), one thing you can't do is polymorphically reach "under" a given part of the transformer stack. For example, there's no polymorphic way to say "I want to run `ask`, but not the outer-most `ask`, the next one down". Here's an idea for how to have that possibility.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE KindSignatures #-} | |
import Control.Monad.Reader (ReaderT) | |
import Control.Monad.State (StateT) | |
import qualified Control.Monad.Reader as R | |
import qualified Control.Monad.State as S | |
class Monad m => DmwitMonadReader m where | |
type Env m | |
type Wrapped m :: * -> * | |
ask :: m (Env m) | |
liftReader :: Wrapped m a -> m a | |
instance Monad m => DmwitMonadReader (ReaderT r m) where | |
type Env (ReaderT r m) = r | |
type Wrapped (ReaderT r m) = m | |
ask = R.ask | |
liftReader = R.lift | |
instance DmwitMonadReader m => DmwitMonadReader (StateT s m) where | |
type Env (StateT s m) = Env m | |
type Wrapped (StateT s m) = Wrapped m | |
ask = S.lift ask | |
liftReader = S.lift . liftReader |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment