%
% (c) The Foo Project, University of Glasgow, 1998
%
% @(#) $Docid: Aug. 21th 2001 23:14 Sigbjorn Finne $
% @(#) $Contactid: sof@galconn.com $
%
Basic name supply monad.
\begin{code}
module NameSupply
( NSM
, getNewName
, withNewName
, getNewNames
, mapNSM
, runNS
) where
\end{code}
%************************************************************************
%* *
\subsection{Monadic plumbing for Name Supply}
%* *
%************************************************************************
\begin{code}
type NameSupply = [String]
newtype NSM a = NSM (NameSupply -> (a, NameSupply))
mapNSM :: (a -> b) -> NSM a -> NSM b
mapNSM f (NSM g) = NSM (\ns -> let (a, ns') = g ns in (f a, ns'))
instance Monad NSM where
(NSM f) >>= g =
NSM (\ns -> let (result1, ns1) = f ns
(NSM h) = g result1
in h ns1)
return a = NSM (\ns -> (a, ns))
getNewNames :: Int -> NSM [String]
getNewNames i = NSM (\ns -> splitAt i ns)
getNewName :: NSM String
getNewName = NSM (\ns -> (head ns, tail ns))
withNewName :: String -> NSM a -> NSM a
withNewName n (NSM f) = NSM $ \ ns ->
case f (n:ns) of
(v, ns') -> case ns' of
(x:xs) | x == n -> (v, xs)
_ -> (v, ns')
runNS :: NSM a -> [String] -> a
runNS (NSM f) ns = fst (f ns)
\end{code}