----------------------------------------------------------------
--
-- | Compilation
--   Monad and combinators for quickly assembling simple
--   compilers.
--
-- @Control\/Compilation\/Fresh.hs@
--
--   State extension class and combinators for implementations
--   of a state that support generation of fresh (i.e., unique)
--   values (integers and strings).
--

----------------------------------------------------------------
--

module Control.Compilation.Fresh
  where

import Control.Compilation

----------------------------------------------------------------
-- | State extension class definition, including combinators
--   and convenient synonyms.

class StateExtension a => Fresh a where
  project :: a -> Integer
  inject :: Integer -> a -> a

  freshInteger :: Compilation a Integer
  freshInteger =
    do s <- get
       i <- return $ project s
       set $ inject (i+1) s
       return $ i

  freshString :: Compilation a String
  freshString =
    do i <- freshInteger
       return $ show i

  freshStringWithPrefix :: String -> Compilation a String
  freshStringWithPrefix prefix =
    do s <- freshString
       return $ prefix ++ s

  freshWithPrefix :: String -> Compilation a String
  freshWithPrefix = freshStringWithPrefix

  fresh :: Compilation a String
  fresh = freshString

  fresh_ :: String -> Compilation a String
  fresh_ = freshStringWithPrefix

  freshes :: Integer -> Compilation a [String]
  freshes i =
    do ns <- mapM (\_ -> fresh) [0..i-1]
       return $ [show n | n <- ns]

  freshes_ :: String -> Integer -> Compilation a [String]
  freshes_ prefix i =
    do ns <- mapM (\_ -> fresh) [0..i-1]
       return $ [prefix ++ show n | n <- ns]

--eof