(original) (raw)

{-# LANGUAGE Trustworthy #-}

module Data.Unique (

Unique, newUnique, hashUnique ) where

import System.IO.Unsafe (unsafePerformIO)

import GHC.Num import Data.IORef

newtype Unique = Unique Integer deriving (Unique -> Unique -> Bool (Unique -> Unique -> Bool) -> (Unique -> Unique -> Bool) -> Eq Unique forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Unique -> Unique -> Bool $c/= :: Unique -> Unique -> Bool == :: Unique -> Unique -> Bool $c== :: Unique -> Unique -> Bool Eq,Eq Unique Eq Unique -> (Unique -> Unique -> Ordering) -> (Unique -> Unique -> Bool) -> (Unique -> Unique -> Bool) -> (Unique -> Unique -> Bool) -> (Unique -> Unique -> Bool) -> (Unique -> Unique -> Unique) -> (Unique -> Unique -> Unique) -> Ord Unique Unique -> Unique -> Bool Unique -> Unique -> Ordering Unique -> Unique -> Unique forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a min :: Unique -> Unique -> Unique $cmin :: Unique -> Unique -> Unique max :: Unique -> Unique -> Unique $cmax :: Unique -> Unique -> Unique

= :: Unique -> Unique -> Bool $c>= :: Unique -> Unique -> Bool :: Unique -> Unique -> Bool $c> :: Unique -> Unique -> Bool <= :: Unique -> Unique -> Bool $c<= :: Unique -> Unique -> Bool < :: Unique -> Unique -> Bool $c< :: Unique -> Unique -> Bool compare :: Unique -> Unique -> Ordering $ccompare :: Unique -> Unique -> Ordering Ord)

uniqSource :: IORef Integer uniqSource :: IORef Integer uniqSource = IO (IORef Integer) -> IORef Integer forall a. IO a -> a unsafePerformIO (Integer -> IO (IORef Integer) forall a. a -> IO (IORef a) newIORef Integer 0) {-# NOINLINE uniqSource #-}

newUnique :: IO Unique newUnique :: IO Unique newUnique = do Integer r <- IORef Integer -> (Integer -> (Integer, Integer)) -> IO Integer forall a b. IORef a -> (a -> (a, b)) -> IO b atomicModifyIORef' IORef Integer uniqSource ((Integer -> (Integer, Integer)) -> IO Integer) -> (Integer -> (Integer, Integer)) -> IO Integer forall a b. (a -> b) -> a -> b $ \Integer x -> let z :: Integer z = Integer xInteger -> Integer -> Integer forall a. Num a => a -> a -> a +Integer 1 in (Integer z,Integer z) Unique -> IO Unique forall (m :: * -> *) a. Monad m => a -> m a return (Integer -> Unique Unique Integer r)

hashUnique :: Unique -> Int hashUnique :: Unique -> Int hashUnique (Unique Integer i) = Integer -> Int integerToInt Integer i