-- | -- Copyright : (c) 2010 Simon Meier -- License : GPL v3 (see LICENSE) -- -- Maintainer : Simon Meier -- Portability : portable -- -- Type-class abstracting computations that need a fresh name supply. 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 -- Added 'Applicative' until base states this hierarchy class (Applicative m, Monad m) => MonadFresh m where -- | Get the integer of the next fresh identifier of this name. freshIdent :: String -- ^ Desired name -> m Integer -- | Get a number of fresh identifiers. This reserves the required number -- of identifiers on all names. freshIdents :: Integer -- ^ Number of desired fresh identifiers. -> m Integer -- ^ The first Fresh identifier. -- | Scope the 'freshIdent' and 'freshIdents' requests such that these -- variables are not marked as used once the scope is left. 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 ---------------------------------------------------------------------------- -- instances for other mtl transformers -- -- TODO: Add remaining ones 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)