module Control.Monad.Supply.Class (
MonadSupply (..)
, demand
) where
import Control.Monad.Trans
import Control.Monad.Trans.Cont
import Control.Monad.Trans.Error
import Control.Monad.Trans.Identity
import Control.Monad.Trans.List
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Reader
import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS
import qualified Control.Monad.Trans.RWS.Strict as StrictRWS
import Control.Monad.Trans.State.Lazy as Lazy
import Control.Monad.Trans.State.Strict as Strict
import Control.Monad.Trans.Supply (SupplyT)
import qualified Control.Monad.Trans.Supply as Supply
import Control.Monad.Trans.Writer.Lazy as Lazy
import Control.Monad.Trans.Writer.Strict as Strict
import Data.Monoid
class Monad m => MonadSupply s f m | m -> s, m -> f where
supply :: (s -> f a) -> m a
provide :: (s -> a) -> m a
demand :: MonadSupply s f m => m s
demand = provide id
instance (Functor m, Monad m) => MonadSupply s m (SupplyT s m) where
supply = Supply.supply
provide = Supply.provide
instance MonadSupply s f m => MonadSupply s f (ContT r m) where
supply = lift . supply
provide = lift . provide
instance (Error e, MonadSupply s f m) => MonadSupply s f (ErrorT e m) where
supply = lift . supply
provide = lift . provide
instance MonadSupply s f m => MonadSupply s f (IdentityT m) where
supply = lift . supply
provide = lift . provide
instance MonadSupply s f m => MonadSupply s f (ListT m) where
supply = lift . supply
provide = lift . provide
instance MonadSupply s f m => MonadSupply s f (MaybeT m) where
supply = lift . supply
provide = lift . provide
instance MonadSupply s f m => MonadSupply s f (ReaderT r m) where
supply = lift . supply
provide = lift . provide
instance (Monoid w, MonadSupply s f m) => MonadSupply s f (LazyRWS.RWST r w s m) where
supply = lift . supply
provide = lift . provide
instance (Monoid w, MonadSupply s f m) => MonadSupply s f (StrictRWS.RWST r w s m) where
supply = lift . supply
provide = lift . provide
instance MonadSupply s f m => MonadSupply s f (Lazy.StateT s m) where
supply = lift . supply
provide = lift . provide
instance MonadSupply s f m => MonadSupply s f (Strict.StateT s m) where
supply = lift . supply
provide = lift . provide
instance (Monoid w, MonadSupply s f m) => MonadSupply s f (Lazy.WriterT w m) where
supply = lift . supply
provide = lift . provide
instance (Monoid w, MonadSupply s f m) => MonadSupply s f (Strict.WriterT w m) where
supply = lift . supply
provide = lift . provide