mapUs, mapAndUnzipUs, mapAndUnzip3Us,
thenMaybeUs, mapAccumLUs,
lazyThenUs, lazyMapUs,
+ module MonadUtils, mapAndUnzipM,
+ MonadUnique(..),
mkSplitUniqSupply,
splitUniqSupply, listSplitUniqSupply
#include "HsVersions.h"
import Unique
-
-import GHC.Exts
-import System.IO.Unsafe ( unsafeInterleaveIO )
+import FastTypes
#if __GLASGOW_HASKELL__ >= 607
import GHC.IOBase (unsafeDupableInterleaveIO)
#else
+import System.IO.Unsafe ( unsafeInterleaveIO )
unsafeDupableInterleaveIO :: IO a -> IO a
unsafeDupableInterleaveIO = unsafeInterleaveIO
#endif
-w2i x = word2Int# x
-i2w x = int2Word# x
-i2w_s x = (x :: Int#)
\end{code}
\begin{code}
data UniqSupply
- = MkSplitUniqSupply Int# -- make the Unique with this
+ = MkSplitUniqSupply FastInt -- make the Unique with this
UniqSupply UniqSupply
-- when split => these two supplies
\end{code}
\end{code}
\begin{code}
-mkSplitUniqSupply (C# c#)
- = let
- mask# = (i2w (ord# c#)) `uncheckedShiftL#` (i2w_s 24#)
+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#
+ mk_supply
= unsafeDupableInterleaveIO (
- genSymZh >>= \ (I# u#) ->
- mk_supply# >>= \ s1 ->
- mk_supply# >>= \ s2 ->
- return (MkSplitUniqSupply (w2i (mask# `or#` (i2w u#))) s1 s2)
- )
- in
- mk_supply#
+ genSymZh >>= \ u_ -> case iUnbox u_ of { u -> (
+ mk_supply >>= \ s1 ->
+ mk_supply >>= \ s2 ->
+ return (MkSplitUniqSupply (mask `bitOrFastInt` u) s1 s2)
+ )})
+ in
+ mk_supply
foreign import ccall unsafe "genSymZh" genSymZh :: IO Int
\end{code}
\begin{code}
-uniqFromSupply (MkSplitUniqSupply n _ _) = mkUniqueGrimily (I# n)
-uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily (I# n) : uniqsFromSupply s2
+uniqFromSupply (MkSplitUniqSupply n _ _) = mkUniqueGrimily (iBox n)
+uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily (iBox n) : uniqsFromSupply s2
\end{code}
%************************************************************************
getUs :: UniqSM UniqSupply
getUs = USM (\us -> splitUniqSupply us)
+-- | A monad for generating unique identifiers
+class Monad m => MonadUnique m where
+ -- | Get a new UniqueSupply
+ getUniqueSupplyM :: m UniqSupply
+ -- | Get a new unique identifier
+ getUniqueM :: m Unique
+ -- | Get an infinite list of new unique identifiers
+ getUniquesM :: m [Unique]
+
+ getUniqueM = liftM uniqFromSupply getUniqueSupplyM
+ getUniquesM = liftM uniqsFromSupply getUniqueSupplyM
+
+instance MonadUnique UniqSM where
+ getUniqueSupplyM = USM (\us -> splitUniqSupply us)
+ getUniqueM = getUniqueUs
+ getUniquesM = getUniquesUs
+
getUniqueUs :: UniqSM Unique
getUniqueUs = USM (\us -> case splitUniqSupply us of
(us1,us2) -> (uniqFromSupply us1, us2))