
newtype UniqT m a = UniqT { runUniqT :: StateT (Map.Map Text Int) m a}
    deriving (Functor, Applicative, Monad, MonadTrans)

class Monad m => MonadUnique m where 
    unique :: Text -> m Text

instance Monad m => MonadUnique (UniqT m) where 
    unique t = do 
        st <- UniqT get
        case Map.lookup t st of 
            Just cnt -> do
                UniqT (put $ Map.insert t (cnt + 1) st)