module Control.Monad.Fresh.Class (
MonadFresh(..)
) where
import Control.Basics
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Writer
import qualified Control.Monad.Trans.FastFresh as Fast
import qualified Control.Monad.Trans.PreciseFresh as Precise
class (Applicative m, Monad m) => MonadFresh m where
freshIdent :: String
-> m Integer
freshIdents :: Integer
-> m Integer
scopeFreshness :: m a -> m a
instance (Functor m, Monad m) => MonadFresh (Fast.FreshT m) where
freshIdent _name = Fast.freshIdents 1
freshIdents = Fast.freshIdents
scopeFreshness = Fast.scopeFreshness
instance (Functor m, Monad m) => MonadFresh (Precise.FreshT m) where
freshIdent = Precise.freshIdent
freshIdents = Precise.freshIdents
scopeFreshness = Precise.scopeFreshness
instance MonadFresh m => MonadFresh (MaybeT m) where
freshIdent = lift . freshIdent
freshIdents = lift . freshIdents
scopeFreshness m = MaybeT $ scopeFreshness (runMaybeT m)
instance MonadFresh m => MonadFresh (StateT s m) where
freshIdent = lift . freshIdent
freshIdents = lift . freshIdents
scopeFreshness m = StateT $ \s -> scopeFreshness (runStateT m s)
instance MonadFresh m => MonadFresh (ReaderT r m) where
freshIdent = lift . freshIdent
freshIdents = lift . freshIdents
scopeFreshness m = ReaderT $ \r -> scopeFreshness (runReaderT m r)
instance (Monoid w, MonadFresh m) => MonadFresh (WriterT w m) where
freshIdent = lift . freshIdent
freshIdents = lift . freshIdents
scopeFreshness m = WriterT $ scopeFreshness (runWriterT m)