Partially complete Monad Transformer exercises
Write Functor, Applicative, Monad instances for: - MaybeT - EitherT - ReaderT
This commit is contained in:
		
							parent
							
								
									3665ea457b
								
							
						
					
					
						commit
						5116cc3463
					
				
					 1 changed files with 79 additions and 0 deletions
				
			
		|  | @ -0,0 +1,79 @@ | |||
| module MonadTransformersScratch where | ||||
| 
 | ||||
| import Data.Function ((&)) | ||||
| -------------------------------------------------------------------------------- | ||||
| 
 | ||||
| newtype MaybeT m a = | ||||
|   MaybeT { runMaybeT :: m (Maybe a) } | ||||
| 
 | ||||
| instance (Functor f) => Functor (MaybeT f) where | ||||
|   fmap f (MaybeT run) = | ||||
|     MaybeT $ (fmap . fmap) f run | ||||
| 
 | ||||
| instance (Applicative m) => Applicative (MaybeT m) where | ||||
|   pure x = x & pure & pure & MaybeT | ||||
|   _ <*> _ = undefined | ||||
| 
 | ||||
| instance (Monad m) => Monad (MaybeT m) where | ||||
|   return = pure | ||||
|   (MaybeT ma) >>= f = MaybeT $ do | ||||
|     maybeX <- ma | ||||
|     case maybeX of | ||||
|       Nothing -> pure Nothing | ||||
|       Just x -> x & f & runMaybeT | ||||
| 
 | ||||
| -------------------------------------------------------------------------------- | ||||
| 
 | ||||
| newtype EitherT e m a = | ||||
|   EitherT { runEitherT :: m (Either e a) } | ||||
| 
 | ||||
| instance (Functor m) => Functor (EitherT e m) where | ||||
|   fmap f (EitherT mEither) = | ||||
|     EitherT $ (fmap . fmap) f mEither | ||||
| 
 | ||||
| instance (Applicative m) => Applicative (EitherT e m) where | ||||
|   pure x = EitherT $ (pure . pure) x | ||||
|   EitherT mEitherF <*> EitherT mEitherX = | ||||
|     EitherT $ (fmap (<*>) mEitherF) <*> mEitherX | ||||
| 
 | ||||
| instance (Monad m) => Monad (EitherT e m) where | ||||
|   return = pure | ||||
|   EitherT mEitherX >>= f = EitherT $ do | ||||
|     eitherX <- mEitherX | ||||
|     case eitherX of | ||||
|       Left x -> pure $ Left x | ||||
|       Right x -> runEitherT $ f x | ||||
| 
 | ||||
| swapEither :: Either l r -> Either r l | ||||
| swapEither (Left x) = Right x | ||||
| swapEither (Right x) = Left x | ||||
| 
 | ||||
| swapEitherT :: (Functor m) => EitherT e m a -> EitherT a m e | ||||
| swapEitherT (EitherT mEitherX) = | ||||
|   EitherT $ fmap swapEither mEitherX | ||||
| 
 | ||||
| eitherT :: Monad m => (a -> m c) -> (b -> m c) -> EitherT a m b -> m c | ||||
| eitherT aToMC bToMC (EitherT mEitherX) = do | ||||
|   eitherX <- mEitherX | ||||
|   case eitherX of | ||||
|     Left x -> aToMC x | ||||
|     Right x -> bToMC x | ||||
| 
 | ||||
| -------------------------------------------------------------------------------- | ||||
| 
 | ||||
| newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a } | ||||
| 
 | ||||
| instance (Functor m) => Functor (ReaderT r m) where | ||||
|   fmap f (ReaderT rma) = | ||||
|     ReaderT $ (fmap . fmap) f rma | ||||
| 
 | ||||
| instance (Applicative m) => Applicative (ReaderT r m) where | ||||
|   pure x = x & pure & pure & ReaderT | ||||
|   ReaderT f <*> ReaderT x = ReaderT $ fmap (<*>) f <*> x | ||||
| 
 | ||||
| instance (Monad m) => Monad (ReaderT r m) where | ||||
|   return = pure | ||||
|   ReaderT rma >>= f = | ||||
|     ReaderT $ \r -> do | ||||
|       a <- rma r | ||||
|       runReaderT (f a) r | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue