@@ -1,20 +1,41 @@
1−module Data.Unique
1+module Data.Unique (Unique, hashUnique, newUnique) where
3− , Unique
3+import Prelude hiding (zero)
6import Effect (Effect)
5import Effect (Effect)
7−import Prelude (class Ord, class Eq, class Show, compare, (==))
6+import Effect.Ref (Ref)
7+import Effect.Ref as Ref
8+import Effect.Unsafe (unsafePerformEffect)
10+-- | An abstract unique object. Objects of type `Unique` may be compared for
11+-- | equality and ordering and hashed into `Int`.
12+foreign import data Unique :: Type
14+foreign import eqImpl :: Unique -> Unique -> Boolean
16+instance Eq Unique where
19+foreign import ordImpl :: Ordering -> Ordering -> Ordering -> Unique -> Unique -> Ordering
21+instance Ord Unique where
22+ compare = ordImpl LT EQ GT
9−newtype Unique = Unique String
24+foreign import addOne :: Unique -> Unique
11−foreign import newUnique :: Effect Unique
26+foreign import zero :: Unique
13−instance showUnique :: Show Unique where
28+-- | Hashes a `Unique` into an `Int`. Two `Unique`s may hash to the same value,
14− show (Unique a) = a
29+-- | although in practice this is unlikely. The `Int` returned makes a good hash
31+foreign import hashUnique :: Unique -> Int
16−instance eqUnique :: Eq Unique where
33+uniqSource :: Ref Unique
17− eq (Unique a) (Unique b) = a == b
34+uniqSource = unsafePerformEffect (Ref.new zero)
19−instance ordUnique :: Ord Unique where
36+-- | Creates a new object of type `Unique`. The value returned will not compare
20− compare (Unique a) (Unique b) = compare a b
37+-- | equal to any other value of type `Unique` returned by previous calls to
38+-- | `newUnique`. There is no limit on the number of times `newUnique` may be
40+newUnique :: Effect Unique
41+newUnique = Ref.modify addOne uniqSource