Revolucent icon

Simple Environment Monad

Revolucent | PRO | 11/25/20 12:02:47 AM UTC (Edited) | 0 ⭐ | 13879 👁️ | Never ⏰ | []
Haskell |

1.27 KB

|

None

|

0 👍

/

0 👎

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

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎