%
\begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
module UniqSupply (
- UniqSupply, -- Abstractly
+ UniqSupply, -- Abstractly
- uniqFromSupply, uniqsFromSupply, -- basic ops
+ uniqFromSupply, uniqsFromSupply, -- basic ops
- UniqSM, -- type: unique supply monad
- initUs, initUs_,
- lazyThenUs, lazyMapUs,
- module MonadUtils, mapAndUnzipM,
- MonadUnique(..),
+ UniqSM, -- type: unique supply monad
+ initUs, initUs_,
+ lazyThenUs, lazyMapUs,
+ mapAndUnzipM,
+ MonadUnique(..),
- mkSplitUniqSupply,
- splitUniqSupply, listSplitUniqSupply
- ) where
+ mkSplitUniqSupply,
+ splitUniqSupply, listSplitUniqSupply,
-#include "HsVersions.h"
+ -- Deprecated:
+ getUniqueUs, getUs, returnUs, thenUs, mapUs
+ ) where
import Unique
import FastTypes
+import MonadUtils
+import Control.Monad
+import Control.Monad.Fix
#if __GLASGOW_HASKELL__ >= 607
import GHC.IOBase (unsafeDupableInterleaveIO)
#else
-import System.IO.Unsafe ( unsafeInterleaveIO )
+import System.IO.Unsafe ( unsafeInterleaveIO )
unsafeDupableInterleaveIO :: IO a -> IO a
unsafeDupableInterleaveIO = unsafeInterleaveIO
#endif
%************************************************************************
-%* *
+%* *
\subsection{Splittable Unique supply: @UniqSupply@}
-%* *
+%* *
%************************************************************************
A value of type @UniqSupply@ is unique, and it can
\begin{code}
data UniqSupply
- = MkSplitUniqSupply FastInt -- make the Unique with this
- UniqSupply UniqSupply
- -- when split => these two supplies
+ = MkSplitUniqSupply FastInt -- make the Unique with this
+ UniqSupply UniqSupply
+ -- when split => these two supplies
\end{code}
\begin{code}
mkSplitUniqSupply :: Char -> IO UniqSupply
splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)
-listSplitUniqSupply :: UniqSupply -> [UniqSupply] -- Infinite
+listSplitUniqSupply :: UniqSupply -> [UniqSupply] -- Infinite
uniqFromSupply :: UniqSupply -> Unique
-uniqsFromSupply :: UniqSupply -> [Unique] -- Infinite
+uniqsFromSupply :: UniqSupply -> [Unique] -- Infinite
\end{code}
\begin{code}
mkSplitUniqSupply c
= case fastOrd (cUnbox c) `shiftLFastInt` _ILIT(24) of
mask -> let
- -- here comes THE MAGIC:
-
- -- This is one of the most hammered bits in the whole compiler
- mk_supply
- = unsafeDupableInterleaveIO (
- genSymZh >>= \ u_ -> case iUnbox u_ of { u -> (
- mk_supply >>= \ s1 ->
- mk_supply >>= \ s2 ->
- return (MkSplitUniqSupply (mask `bitOrFastInt` u) s1 s2)
- )})
+ -- here comes THE MAGIC:
+
+ -- This is one of the most hammered bits in the whole compiler
+ mk_supply
+ = unsafeDupableInterleaveIO (
+ genSymZh >>= \ u_ -> case iUnbox u_ of { u -> (
+ mk_supply >>= \ s1 ->
+ mk_supply >>= \ s2 ->
+ return (MkSplitUniqSupply (mask `bitOrFastInt` u) s1 s2)
+ )})
in
mk_supply
\end{code}
%************************************************************************
-%* *
+%* *
\subsubsection[UniqSupply-monad]{@UniqSupply@ monad: @UniqSM@}
-%* *
+%* *
%************************************************************************
\begin{code}
(>>=) = thenUs
(>>) = thenUs_
+instance Functor UniqSM where
+ fmap f (USM x) = USM (\us -> case x us of
+ (r, us') -> (f r, us'))
+
+instance Applicative UniqSM where
+ pure = returnUs
+ (USM f) <*> (USM x) = USM $ \us -> case f us of
+ (ff, us') -> case x us' of
+ (xx, us'') -> (ff xx, us'')
+
-- the initUs function also returns the final UniqSupply; initUs_ drops it
initUs :: UniqSupply -> UniqSM a -> (a,UniqSupply)
initUs init_us m = case unUSM m init_us of { (r,us) -> (r,us) }
initUs_ :: UniqSupply -> UniqSM a -> a
-initUs_ init_us m = case unUSM m init_us of { (r,us) -> r }
+initUs_ init_us m = case unUSM m init_us of { (r, _) -> r }
{-# INLINE thenUs #-}
{-# INLINE lazyThenUs #-}
thenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b
thenUs (USM expr) cont
- = USM (\us -> case (expr us) of
- (result, us') -> unUSM (cont result) us')
+ = USM (\us -> case (expr us) of
+ (result, us') -> unUSM (cont result) us')
lazyThenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b
lazyThenUs (USM expr) cont
returnUs :: a -> UniqSM a
returnUs result = USM (\us -> (result, us))
-withUs :: (UniqSupply -> (a, UniqSupply)) -> UniqSM a
-withUs f = USM (\us -> f us) -- Ha ha!
-
getUs :: UniqSM UniqSupply
getUs = USM (\us -> splitUniqSupply us)
getUniqueM :: m Unique
-- | Get an infinite list of new unique identifiers
getUniquesM :: m [Unique]
-
+
getUniqueM = liftM uniqFromSupply getUniqueSupplyM
getUniquesM = liftM uniqsFromSupply getUniqueSupplyM
getUniqueUs :: UniqSM Unique
getUniqueUs = USM (\us -> case splitUniqSupply us of
- (us1,us2) -> (uniqFromSupply us1, us2))
+ (us1,us2) -> (uniqFromSupply us1, us2))
getUniquesUs :: UniqSM [Unique]
getUniquesUs = USM (\us -> case splitUniqSupply us of
- (us1,us2) -> (uniqsFromSupply us1, us2))
+ (us1,us2) -> (uniqsFromSupply us1, us2))
+
+mapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b]
+mapUs _ [] = returnUs []
+mapUs f (x:xs)
+ = f x `thenUs` \ r ->
+ mapUs f xs `thenUs` \ rs ->
+ returnUs (r:rs)
\end{code}
\begin{code}
{-# -- SPECIALIZE mapAndUnzip3M :: (a -> UniqSM (b,c,d)) -> [a] -> UniqSM ([b],[c],[d]) #-}
lazyMapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b]
-lazyMapUs f [] = returnUs []
+lazyMapUs _ [] = returnUs []
lazyMapUs f (x:xs)
= f x `lazyThenUs` \ r ->
lazyMapUs f xs `lazyThenUs` \ rs ->
returnUs (r:rs)
-
\end{code}