----------------------------------------------------------------------------- -- -- Module : Control.Monad.Supply -- Copyright : (c) Phil Freeman 2014 -- License : MIT -- -- Maintainer : Phil Freeman -- Stability : experimental -- Portability : -- -- | -- Fresh variable supply -- ----------------------------------------------------------------------------- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE CPP #-} module Control.Monad.Supply where import Data.Functor.Identity #if __GLASGOW_HASKELL__ < 710 import Control.Applicative #endif import Control.Monad.State import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Reader import Control.Monad.Writer newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a } deriving (Functor, Applicative, Monad, MonadTrans, MonadError e, MonadWriter w, MonadReader r) runSupplyT :: Integer -> SupplyT m a -> m (a, Integer) runSupplyT n = flip runStateT n . unSupplyT evalSupplyT :: (Functor m) => Integer -> SupplyT m a -> m a evalSupplyT n = fmap fst . runSupplyT n type Supply = SupplyT Identity runSupply :: Integer -> Supply a -> (a, Integer) runSupply n = runIdentity . runSupplyT n evalSupply :: Integer -> Supply a -> a evalSupply n = runIdentity . evalSupplyT n