-- | -- Module : Basement.Compat.MonadTrans -- License : BSD-style -- Maintainer : Psychohistorians -- Stability : experimental -- Portability : portable -- -- An internal and really simple monad transformers, -- without any bells and whistse. module Basement.Compat.MonadTrans ( State(..) , Reader(..) ) where import Basement.Compat.Base import Control.Monad ((>=>)) -- | Simple State monad newtype State s m a = State { runState :: s -> m (a, s) } instance Monad m => Functor (State s m) where fmap f fa = State $ runState fa >=> (\(a, s2) -> return (f a, s2)) instance Monad m => Applicative (State s m) where pure a = State $ \st -> return (a,st) fab <*> fa = State $ \s1 -> do (ab,s2) <- runState fab s1 (a,s3) <- runState fa s2 return (ab a, s3) instance Monad m => Monad (State r m) where return a = State $ \st -> return (a,st) ma >>= mb = State $ \s1 -> do (a,s2) <- runState ma s1 runState (mb a) s2 -- | Simple Reader monad newtype Reader r m a = Reader { runReader :: r -> m a } instance Monad m => Functor (Reader r m) where fmap f fa = Reader $ runReader fa >=> (\a -> return (f a)) instance Monad m => Applicative (Reader r m) where pure a = Reader $ \_ -> return a fab <*> fa = Reader $ \r -> do a <- runReader fa r ab <- runReader fab r return $ ab a instance Monad m => Monad (Reader r m) where return a = Reader $ \_ -> return a ma >>= mb = Reader $ \r -> do a <- runReader ma r runReader (mb a) r