
\subsection{Identifier generator}

Generates unique elements but elements can be declared as unused, again.

\begin{haskelllisting}

> module Haskore.General.IdGeneratorSet where

> import Data.Set (Set)
> import qualified Data.Set as Set
> import Control.Monad.RWS(RWS, evalRWS, modify, get, when, ask)

\end{haskelllisting}

The generator is a reader+state monad
where the state consists of the allocated identifiers
and the reader source is the least element ever used.

\begin{haskelllisting}

> type T i a = RWS i () (Set i) a

> run :: i -> T i a -> a
> run start gen = fst $ evalRWS gen start Set.empty

\end{haskelllisting}

Reserve a new id.

\begin{haskelllisting}

> alloc :: (Ord i, Enum i) => T i i
> alloc =
>    do start <- ask
>       allocated <- get
>       let newId = head $ filter (not . flip Set.member allocated) [start ..]
>       modify (Set.insert newId)
>       return newId

\end{haskelllisting}

Deallocate an id.

\begin{haskelllisting}

> free :: (Ord i, Enum i) => i -> T i ()
> free oldId =
>    do allocated <- get
>       when (not $ Set.member oldId allocated)
>            (error "IdGeneratorSet.free: deallocated free identifier")
>       modify (Set.delete oldId)

\end{haskelllisting}
