Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {-# LANGUAGE FlexibleInstances #-}
- {-# LANGUAGE MultiParamTypeClasses #-}
- module Lib where
- {-
- This is a simple environment Monad transformer called simply E. It has no
- use whatsoever except to show the basics of how to construct such a thing.
- It turns out that it's easier in most cases to write a monad transformer
- than it is to write a monad, because the "heavy lifting" can in most cases
- be forwarded to the transformed monad. (At the cost of some efficiency,
- though newtype helps a lot with this.)
- Don't use this. Use ReaderT instead.
- -}
- import Control.Monad.IO.Class (MonadIO(..))
- import Control.Monad.Reader.Class (MonadReader(..))
- import Control.Monad.Trans (MonadTrans(..))
- newtype E r m a = E { runE :: r -> m a }
- instance Functor m => Functor (E r m) where
- fmap f (E a) = E $ fmap f . a
- instance Applicative m => Applicative (E r m) where
- pure = E . const . pure
- (E f) <*> (E a) = E $ \r -> f r <*> a r
- instance Monad m => Monad (E r m) where
- return = pure
- (E a) >>= f = E $ \r -> a r >>= \b -> runE (f b) r
- instance MonadTrans (E r) where
- lift = E . const
- instance MonadIO m => MonadIO (E r m) where
- liftIO = lift . liftIO
- instance Monad m => MonadReader r (E r m) where
- ask = E return
- local t (E a) = E $ a . t
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement