    {-
    (c) The University of Glasgow 2006
    (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
    -}

    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE PatternSynonyms #-}
    {-# LANGUAGE UnboxedTuples #-}

    module GHC.Types.Unique.Supply (
            -- * Main data type
            UniqSupply, -- Abstractly

            -- ** Operations on supplies
            uniqFromSupply, uniqsFromSupply, -- basic ops
            takeUniqFromSupply, uniqFromMask,

            mkSplitUniqSupply,
            splitUniqSupply, listSplitUniqSupply,

            -- * Unique supply monad and its abstraction
            UniqSM, MonadUnique(..),

            -- ** Operations on the monad
            initUs, initUs_,

            -- * Set supply strategy
            initUniqSupply
      ) where

    import GHC.Prelude

    import GHC.Types.Unique
    import GHC.Utils.Panic.Plain

    import GHC.IO

    import GHC.Utils.Monad
    import Control.Monad
    import Data.Char
    import GHC.Exts( Ptr(..), noDuplicate#, oneShot )
    #if MIN_VERSION_GLASGOW_HASKELL(9,1,0,0)
    import GHC.Exts( Int(..), word2Int#, fetchAddWordAddr#, plusWord#, readWordOffAddr# )
    #if defined(DEBUG)
    import GHC.Utils.Misc
    #endif
    #endif
    import Foreign.Storable

    #include "Unique.h"
    #include "HsVersions.h"

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Splittable Unique supply: @UniqSupply@}
    *                                                                      *
    ************************************************************************
    -}

    {- Note [How the unique supply works]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The basic idea (due to Lennart Augustsson) is that a UniqSupply is
    lazily-evaluated infinite tree.

    * At each MkSplitUniqSupply node is a unique Int, and two
      sub-trees (see data UniqSupply)

    * takeUniqFromSupply :: UniqSupply -> (Unique, UniqSupply)
      returns the unique Int and one of the sub-trees

    * splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)
      returns the two sub-trees

    * When you poke on one of the thunks, it does a foreign call
      to get a fresh Int from a thread-safe counter, and returns
      a fresh MkSplitUniqSupply node.  This has to be as efficient
      as possible: it should allocate only
         * The fresh node
         * A thunk for each sub-tree

    Note [How unique supplies are used]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The general design (used throughout GHC) is to:

    * For creating new uniques either a UniqSupply is used and threaded through
      or for monadic code a MonadUnique instance might conjure up uniques using
      `uniqFromMask`.
    * Different parts of the compiler will use a UniqSupply or MonadUnique instance
      with a specific mask. This way the different parts of the compiler will
      generate uniques with different masks.

    If different code shares the same mask then care has to be taken that all uniques
    still get distinct numbers. Usually this is done by relying on genSym which
    has *one* counter per GHC invocation that is relied on by all calls to it.
    But using something like the address for pinned objects works as well and in fact is done
    for fast strings.

    This is important for example in the simplifier. Most passes of the simplifier use
    the same mask 's'. However in some places we create a unique supply using `mkSplitUniqSupply`
    and thread it through the code, while in GHC.Core.Opt.Simplify.Monad  we use the
    `instance MonadUnique SimplM`, which uses `mkSplitUniqSupply` in getUniqueSupplyM
    and `uniqFromMask` in getUniqeM.

    Ultimately all these boil down to each new unique consisting of the mask and the result from
    a call to `genSym`. The later producing a distinct number for each invocation ensuring
    uniques are distinct.

    Note [Optimising the unique supply]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The inner loop of mkSplitUniqSupply is a function closure

         mk_supply s0 =
            case noDuplicate# s0 of { s1 ->
            case unIO genSym s1 of { (# s2, u #) ->
            case unIO (unsafeDupableInterleaveIO (IO mk_supply)) s2 of { (# s3, x #) ->
            case unIO (unsafeDupableInterleaveIO (IO mk_supply)) s3 of { (# s4, y #) ->
            (# s4, MkSplitUniqSupply (mask .|. u) x y #)
            }}}}

    It's a classic example of an IO action that is captured and then called
    repeatedly (see #18238 for some discussion). It mustn't allocate!  The test
    perf/should_run/UniqLoop keeps track of this loop.  Watch it carefully.

    We used to write it as:

         mk_supply :: IO UniqSupply
         mk_supply = unsafeInterleaveIO $
                     genSym      >>= \ u ->
                     mk_supply   >>= \ s1 ->
                     mk_supply   >>= \ s2 ->
                     return (MkSplitUniqSupply (mask .|. u) s1 s2)

    and to rely on -fno-state-hack, full laziness and inlining to get the same
    result. It was very brittle and required enabling -fno-state-hack globally. So
    it has been rewritten using lower level constructs to explicitly state what we
    want.

    Note [Optimising use of unique supplies]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    When it comes to having a way to generate new Uniques
    there are generally three ways to deal with this:

    For pure code the only good approach is to take an UniqSupply
    as argument. Then  thread it through the code splitting it
    for sub-passes or when creating uniques.
    The code for this is about as optimized as it gets, but we can't
    get around the need to allocate one `UniqSupply` for each Unique
    we need.

    For code in IO we can improve on this by threading only the *mask*
    we are going to use for Uniques. Using `uniqFromMask` to
    generate uniques as needed. This gets rid of the overhead of
    allocating a new UniqSupply for each unique generated. It also avoids
    frequent state updates when the Unique/Mask is part of the state in a
    state monad.

    For monadic code in IO which always uses the same mask we can go further
    and hardcode the mask into the MonadUnique instance. On top of all the
    benefits of threading the mask this *also* has the benefit of avoiding
    the mask getting captured in thunks, or being passed around at runtime.
    It does however come at the cost of having to use a fixed Mask for all
    code run in this Monad. But rememeber, the Mask is purely cosmetic:
    See Note [Uniques and masks].

    NB: It's *not* an optimization to pass around the UniqSupply inside an
    IORef instead of the mask. While this would avoid frequent state updates
    it still requires allocating one UniqSupply per Unique. On top of some
    overhead for reading/writing to/from the IORef.

    All of this hinges on the assumption that UniqSupply and
    uniqFromMask use the same source of distinct numbers (`genSym`) which
    allows both to be used at the same time, with the same mask, while still
    ensuring distinct uniques.
    One might consider this fact to be an "accident". But GHC worked like this
    as far back as source control history goes. It also allows the later two
    optimizations to be used. So it seems safe to depend on this fact.

    -}

    -- | Unique Supply
    --
    -- A value of type 'UniqSupply' is unique, and it can
    -- supply /one/ distinct 'Unique'.  Also, from the supply, one can
    -- also manufacture an arbitrary number of further 'UniqueSupply' values,
    -- which will be distinct from the first and from all others.
    data UniqSupply
      = MkSplitUniqSupply {-# UNPACK #-} !Int -- make the Unique with this
                       UniqSupply UniqSupply
                                    -- when split => these two supplies

    mkSplitUniqSupply :: Char -> IO UniqSupply
    -- ^ Create a unique supply out of thin air.
    -- The "mask" (Char) supplied is purely cosmetic, making it easier
    -- to figure out where a Unique was born. See
    -- Note [Uniques and masks].
    --
    -- The payload part of the Uniques allocated from this UniqSupply are
    -- guaranteed distinct wrt all other supplies, regardless of their "mask".
    -- This is achieved by allocating the payload part from
    -- a single source of Uniques, namely `genSym`, shared across
    -- all UniqSupply's.

    -- See Note [How the unique supply works]
    -- See Note [Optimising the unique supply]
    mkSplitUniqSupply :: Char -> IO UniqSupply
    mkSplitUniqSupply Char
    c
      = forall a. IO a -> IO a
    unsafeDupableInterleaveIO (forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO State# RealWorld -> (# State# RealWorld, UniqSupply #)
    mk_supply)

      where
         !mask :: Int
    mask = Char -> Int
    ord Char
    c forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    uNIQUE_BITS

            -- Here comes THE MAGIC: see Note [How the unique supply works]
            -- This is one of the most hammered bits in the whole compiler
            -- See Note [Optimising the unique supply]
            -- NB: Use noDuplicate# for thread-safety.
         mk_supply :: State# RealWorld -> (# State# RealWorld, UniqSupply #)
    mk_supply State# RealWorld
    s0 =
            case forall d. State# d -> State# d
    noDuplicate# State# RealWorld
    s0 of { State# RealWorld
    s1 ->
            case forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
    unIO IO Int
    genSym State# RealWorld
    s1 of { (# State# RealWorld
    s2, Int
    u #) ->
            -- deferred IO computations
            case forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
    unIO (forall a. IO a -> IO a
    unsafeDupableInterleaveIO (forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO State# RealWorld -> (# State# RealWorld, UniqSupply #)
    mk_supply)) State# RealWorld
    s2 of { (# State# RealWorld
    s3, UniqSupply
    x #) ->
            case forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
    unIO (forall a. IO a -> IO a
    unsafeDupableInterleaveIO (forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO State# RealWorld -> (# State# RealWorld, UniqSupply #)
    mk_supply)) State# RealWorld
    s3 of { (# State# RealWorld
    s4, UniqSupply
    y #) ->
            (# State# RealWorld
    s4, Int -> UniqSupply -> UniqSupply -> UniqSupply
    MkSplitUniqSupply (Int
    mask forall a. Bits a => a -> a -> a
    .|. Int
    u) UniqSupply
    x UniqSupply
    y #)
            }}}}

    #if !MIN_VERSION_GLASGOW_HASKELL(9,1,0,0)
    foreign import ccall unsafe "genSym" genSym :: IO Int
    #else
    genSym :: IO Int
    genSym :: IO Int
    genSym = do
        let !mask :: Int
    mask = (Int
    1 forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    uNIQUE_BITS) forall a. Num a => a -> a -> a
    - Int
    1
        let !(Ptr Addr#
    counter) = Ptr Word
    ghc_unique_counter
        let !(Ptr Addr#
    inc_ptr) = Ptr Int
    ghc_unique_inc
        Int
    u <- forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
    IO forall a b. (a -> b) -> a -> b
    $ \State# RealWorld
    s0 -> case forall d. Addr# -> Int# -> State# d -> (# State# d, Word# #)
    readWordOffAddr# Addr#
    inc_ptr Int#
    0# State# RealWorld
    s0 of
            (# State# RealWorld
    s1, Word#
    inc #) -> case forall d. Addr# -> Word# -> State# d -> (# State# d, Word# #)
    fetchAddWordAddr# Addr#
    counter Word#
    inc State# RealWorld
    s1 of
                (# State# RealWorld
    s2, Word#
    val #) ->
                    let !u :: Int
    u = Int# -> Int
    I# (Word# -> Int#
    word2Int# (Word#
    val Word# -> Word# -> Word#
    `plusWord#` Word#
    inc)) forall a. Bits a => a -> a -> a
    .&. Int
    mask
                    in (# State# RealWorld
    s2, Int
    u #)
    #if defined(DEBUG)
        -- Uh oh! We will overflow next time a unique is requested.
        -- (Note that if the increment isn't 1 we may miss this check)
        MASSERT(u /= mask)
    #endif
        forall (m :: * -> *) a. Monad m => a -> m a
    return Int
    u
    #endif

    foreign import ccall unsafe "&ghc_unique_counter" ghc_unique_counter :: Ptr Word
    foreign import ccall unsafe "&ghc_unique_inc"     ghc_unique_inc     :: Ptr Int

    initUniqSupply :: Word -> Int -> IO ()
    initUniqSupply :: Word -> Int -> IO ()
    initUniqSupply Word
    counter Int
    inc = do
        forall a. Storable a => Ptr a -> a -> IO ()
    poke Ptr Word
    ghc_unique_counter Word
    counter
        forall a. Storable a => Ptr a -> a -> IO ()
    poke Ptr Int
    ghc_unique_inc     Int
    inc

    uniqFromMask :: Char -> IO Unique
    uniqFromMask :: Char -> IO Unique
    uniqFromMask !Char
    mask
      = do { Int
    uqNum <- IO Int
    genSym
           ; forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $! Char -> Int -> Unique
    mkUnique Char
    mask Int
    uqNum }

    splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)
    -- ^ Build two 'UniqSupply' from a single one, each of which
    -- can supply its own 'Unique'.
    listSplitUniqSupply :: UniqSupply -> [UniqSupply]
    -- ^ Create an infinite list of 'UniqSupply' from a single one
    uniqFromSupply  :: UniqSupply -> Unique
    -- ^ Obtain the 'Unique' from this particular 'UniqSupply'
    uniqsFromSupply :: UniqSupply -> [Unique] -- Infinite
    -- ^ Obtain an infinite list of 'Unique' that can be generated by constant splitting of the supply
    takeUniqFromSupply :: UniqSupply -> (Unique, UniqSupply)
    -- ^ Obtain the 'Unique' from this particular 'UniqSupply', and a new supply

    splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply)
    splitUniqSupply (MkSplitUniqSupply Int
    _ UniqSupply
    s1 UniqSupply
    s2) = (UniqSupply
    s1, UniqSupply
    s2)
    listSplitUniqSupply :: UniqSupply -> [UniqSupply]
    listSplitUniqSupply  (MkSplitUniqSupply Int
    _ UniqSupply
    s1 UniqSupply
    s2) = UniqSupply
    s1 forall a. a -> [a] -> [a]
    : UniqSupply -> [UniqSupply]
    listSplitUniqSupply UniqSupply
    s2

    uniqFromSupply :: UniqSupply -> Unique
    uniqFromSupply  (MkSplitUniqSupply Int
    n UniqSupply
    _ UniqSupply
    _)  = Int -> Unique
    mkUniqueGrimily Int
    n
    uniqsFromSupply :: UniqSupply -> [Unique]
    uniqsFromSupply (MkSplitUniqSupply Int
    n UniqSupply
    _ UniqSupply
    s2) = Int -> Unique
    mkUniqueGrimily Int
    n forall a. a -> [a] -> [a]
    : UniqSupply -> [Unique]
    uniqsFromSupply UniqSupply
    s2
    takeUniqFromSupply :: UniqSupply -> (Unique, UniqSupply)
    takeUniqFromSupply (MkSplitUniqSupply Int
    n UniqSupply
    s1 UniqSupply
    _) = (Int -> Unique
    mkUniqueGrimily Int
    n, UniqSupply
    s1)

    {-
    ************************************************************************
    *                                                                      *
    \subsubsection[UniqSupply-monad]{@UniqSupply@ monad: @UniqSM@}
    *                                                                      *
    ************************************************************************
    -}

    type UniqResult result = (# result, UniqSupply #)

    pattern UniqResult :: a -> b -> (# a, b #)
    pattern $mUniqResult :: forall {r} {a} {b}.
    (# a, b #) -> (a -> b -> r) -> ((# #) -> r) -> r
    $bUniqResult :: forall a b. a -> b -> (# a, b #)
    UniqResult x y = (# x, y #)
    {-# COMPLETE UniqResult #-}

    -- | A monad which just gives the ability to obtain 'Unique's
    newtype UniqSM result = USM { forall result. UniqSM result -> UniqSupply -> UniqResult result
    unUSM :: UniqSupply -> UniqResult result }

    -- See Note [The one-shot state monad trick] for why we don't derive this.
    instance Functor UniqSM where
      fmap :: forall a b. (a -> b) -> UniqSM a -> UniqSM b
    fmap a -> b
    f (USM UniqSupply -> UniqResult a
    m) = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM forall a b. (a -> b) -> a -> b
    $ \UniqSupply
    us ->
          case UniqSupply -> UniqResult a
    m UniqSupply
    us of
            (# a
    r, UniqSupply
    us' #) -> forall a b. a -> b -> (# a, b #)
    UniqResult (a -> b
    f a
    r) UniqSupply
    us'

    -- | Smart constructor for 'UniqSM', as described in Note [The one-shot state
    -- monad trick].
    mkUniqSM :: (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM :: forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM UniqSupply -> UniqResult a
    f = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    USM (oneShot :: forall a b. (a -> b) -> a -> b
    oneShot UniqSupply -> UniqResult a
    f)
    {-# INLINE mkUniqSM #-}

    instance Monad UniqSM where
      >>= :: forall a b. UniqSM a -> (a -> UniqSM b) -> UniqSM b
    (>>=) = forall a b. UniqSM a -> (a -> UniqSM b) -> UniqSM b
    thenUs
      >> :: forall a b. UniqSM a -> UniqSM b -> UniqSM b
    (>>)  = forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    (*>)

    instance Applicative UniqSM where
        pure :: forall a. a -> UniqSM a
    pure = forall a. a -> UniqSM a
    returnUs
        (USM UniqSupply -> UniqResult (a -> b)
    f) <*> :: forall a b. UniqSM (a -> b) -> UniqSM a -> UniqSM b
    <*> (USM UniqSupply -> UniqResult a
    x) = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM forall a b. (a -> b) -> a -> b
    $ \UniqSupply
    us0 -> case UniqSupply -> UniqResult (a -> b)
    f UniqSupply
    us0 of
                                UniqResult a -> b
    ff UniqSupply
    us1 -> case UniqSupply -> UniqResult a
    x UniqSupply
    us1 of
                                  UniqResult a
    xx UniqSupply
    us2 -> forall a b. a -> b -> (# a, b #)
    UniqResult (a -> b
    ff a
    xx) UniqSupply
    us2
        *> :: forall a b. UniqSM a -> UniqSM b -> UniqSM b
    (*>) = forall a b. UniqSM a -> UniqSM b -> UniqSM b
    thenUs_

    -- TODO: try to get rid of this instance
    instance MonadFail UniqSM where
        fail :: forall a. String -> UniqSM a
    fail = forall a. String -> a
    panic

    -- | Run the 'UniqSM' action, returning the final 'UniqSupply'
    initUs :: UniqSupply -> UniqSM a -> (a, UniqSupply)
    initUs :: forall a. UniqSupply -> UniqSM a -> (a, UniqSupply)
    initUs UniqSupply
    init_us UniqSM a
    m = case forall result. UniqSM result -> UniqSupply -> UniqResult result
    unUSM UniqSM a
    m UniqSupply
    init_us of { UniqResult a
    r UniqSupply
    us -> (a
    r, UniqSupply
    us) }

    -- | Run the 'UniqSM' action, discarding the final 'UniqSupply'
    initUs_ :: UniqSupply -> UniqSM a -> a
    initUs_ :: forall a. UniqSupply -> UniqSM a -> a
    initUs_ UniqSupply
    init_us UniqSM a
    m = case forall result. UniqSM result -> UniqSupply -> UniqResult result
    unUSM UniqSM a
    m UniqSupply
    init_us of { UniqResult a
    r UniqSupply
    _ -> a
    r }

    {-# INLINE thenUs #-}
    {-# INLINE returnUs #-}
    {-# INLINE splitUniqSupply #-}

    -- @thenUs@ is where we split the @UniqSupply@.

    liftUSM :: UniqSM a -> UniqSupply -> (a, UniqSupply)
    liftUSM :: forall a. UniqSM a -> UniqSupply -> (a, UniqSupply)
    liftUSM (USM UniqSupply -> UniqResult a
    m) UniqSupply
    us0 = case UniqSupply -> UniqResult a
    m UniqSupply
    us0 of UniqResult a
    a UniqSupply
    us1 -> (a
    a, UniqSupply
    us1)

    instance MonadFix UniqSM where
        mfix :: forall a. (a -> UniqSM a) -> UniqSM a
    mfix a -> UniqSM a
    m = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us0 -> let (a
    r,UniqSupply
    us1) = forall a. UniqSM a -> UniqSupply -> (a, UniqSupply)
    liftUSM (a -> UniqSM a
    m a
    r) UniqSupply
    us0 in forall a b. a -> b -> (# a, b #)
    UniqResult a
    r UniqSupply
    us1)

    thenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b
    thenUs :: forall a b. UniqSM a -> (a -> UniqSM b) -> UniqSM b
    thenUs (USM UniqSupply -> UniqResult a
    expr) a -> UniqSM b
    cont
      = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us0 -> case (UniqSupply -> UniqResult a
    expr UniqSupply
    us0) of
                       UniqResult a
    result UniqSupply
    us1 -> forall result. UniqSM result -> UniqSupply -> UniqResult result
    unUSM (a -> UniqSM b
    cont a
    result) UniqSupply
    us1)

    thenUs_ :: UniqSM a -> UniqSM b -> UniqSM b
    thenUs_ :: forall a b. UniqSM a -> UniqSM b -> UniqSM b
    thenUs_ (USM UniqSupply -> UniqResult a
    expr) (USM UniqSupply -> UniqResult b
    cont)
      = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us0 -> case (UniqSupply -> UniqResult a
    expr UniqSupply
    us0) of { UniqResult a
    _ UniqSupply
    us1 -> UniqSupply -> UniqResult b
    cont UniqSupply
    us1 })

    returnUs :: a -> UniqSM a
    returnUs :: forall a. a -> UniqSM a
    returnUs a
    result = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us -> forall a b. a -> b -> (# a, b #)
    UniqResult a
    result UniqSupply
    us)

    getUs :: UniqSM UniqSupply
    getUs :: UniqSM UniqSupply
    getUs = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us0 -> case UniqSupply -> (UniqSupply, UniqSupply)
    splitUniqSupply UniqSupply
    us0 of (UniqSupply
    us1,UniqSupply
    us2) -> forall a b. a -> b -> (# a, b #)
    UniqResult UniqSupply
    us1 UniqSupply
    us2)

    -- | 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]

        -- This default definition of getUniqueM, while correct, is not as
        -- efficient as it could be since it needlessly generates and throws away
        -- an extra Unique. For your instances consider providing an explicit
        -- definition for 'getUniqueM' which uses 'takeUniqFromSupply' directly.
        getUniqueM  = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM UniqSupply -> Unique
    uniqFromSupply  forall (m :: * -> *). MonadUnique m => m UniqSupply
    getUniqueSupplyM
        getUniquesM = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM UniqSupply -> [Unique]
    uniqsFromSupply forall (m :: * -> *). MonadUnique m => m UniqSupply
    getUniqueSupplyM

    instance MonadUnique UniqSM where
        getUniqueSupplyM :: UniqSM UniqSupply
    getUniqueSupplyM = UniqSM UniqSupply
    getUs
        getUniqueM :: UniqSM Unique
    getUniqueM  = UniqSM Unique
    getUniqueUs
        getUniquesM :: UniqSM [Unique]
    getUniquesM = UniqSM [Unique]
    getUniquesUs

    getUniqueUs :: UniqSM Unique
    getUniqueUs :: UniqSM Unique
    getUniqueUs = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us0 -> case UniqSupply -> (Unique, UniqSupply)
    takeUniqFromSupply UniqSupply
    us0 of
                               (Unique
    u,UniqSupply
    us1) -> forall a b. a -> b -> (# a, b #)
    UniqResult Unique
    u UniqSupply
    us1)

    getUniquesUs :: UniqSM [Unique]
    getUniquesUs :: UniqSM [Unique]
    getUniquesUs = forall a. (UniqSupply -> UniqResult a) -> UniqSM a
    mkUniqSM (\UniqSupply
    us0 -> case UniqSupply -> (UniqSupply, UniqSupply)
    splitUniqSupply UniqSupply
    us0 of
                                (UniqSupply
    us1,UniqSupply
    us2) -> forall a b. a -> b -> (# a, b #)
    UniqResult (UniqSupply -> [Unique]
    uniqsFromSupply UniqSupply
    us1) UniqSupply
    us2)