vault-0.3.1.6: src/Data/Unique/Really.hs
-- | An abstract interface to a unique symbol generator.
module Data.Unique.Really (
Unique, newUnique, hashUnique,
) where
import Data.Hashable
#if UseGHC
import Control.Exception (evaluate)
import qualified Data.Unique
import System.Mem.StableName
-- | An abstract unique value.
-- Values of type 'Unique' may be compared for equality
-- and hashed into Int.
--
-- Note: Unlike the symbols from "Data.Unique", the symbols from this
-- module do not become equal after reloads in the GHC interpreter!
newtype Unique = Unique (StableName Data.Unique.Unique) deriving (Eq)
newUnique = do
x <- Data.Unique.newUnique
_ <- evaluate x
Unique <$> makeStableName x
hashUnique (Unique s) = hashStableName s
#else
import Data.IORef
import System.IO.Unsafe (unsafePerformIO)
{-# NOINLINE refNumber #-}
refNumber :: IORef Integer
refNumber = unsafePerformIO $ newIORef 0
newNumber = atomicModifyIORef' refNumber $ \x -> let x' = x+1 in (x', x')
-- | An abstract unique value.
-- Values of type 'Unique' may be compared for equality
-- and hashed into Int.
--
-- NOTE: You haven't compiled this module with GHC.
-- The functionality will be identitcal to "Data.Unique".
newtype Unique = Unique Integer deriving (Eq,Ord)
newUnique = Unique <$> newNumber
hashUnique (Unique s) = fromIntegral s
#endif
instance Hashable Unique where hashWithSalt s = hashWithSalt s . hashUnique
-- | Creates a new object of type 'Unique'.
-- The value returned will not compare equal to any other
-- value of type 'Unique' returned by previous calls to 'newUnique'.
-- There is no limit on the number of times you may call this function.
newUnique :: IO Unique
-- | Hashes a 'Unique' into an 'Int'.
-- Two Uniques may hash to the same value, although in practice this is unlikely.
-- The 'Int' returned makes a good hash key.
hashUnique :: Unique -> Int