mirror of
https://github.com/rowtype-yoga/purescript-unique.git
synced 2024-11-22 12:52:16 +03:00
Update Unique implementation to use BigInt.
This commit is contained in:
parent
febb07ba50
commit
a06a9117a0
1
LICENSE
1
LICENSE
@ -1,6 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015-2017 mechairoi
|
||||
Copyright (c) The University of Glasgow (Documentation)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -18,7 +18,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"purescript-prelude": "^6.0.0",
|
||||
"purescript-effect": "^4.0.0"
|
||||
"purescript-effect": "^4.0.0",
|
||||
"purescript-refs": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"purescript-console": "^6.0.0",
|
||||
|
@ -16,6 +16,7 @@
|
||||
"description": "Data.Unique for PureScript",
|
||||
"dependencies": {
|
||||
"prelude": ">=6.0.0 <7.0.0",
|
||||
"effect": ">=4.0.0 <5.0.0"
|
||||
"effect": ">=4.0.0 <5.0.0",
|
||||
"refs": ">=6.0.0 <7.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ name = "unique"
|
||||
, dependencies = [ "effect", "prelude" ]
|
||||
, dependencies = [ "effect", "prelude", "refs" ]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs" ]
|
||||
}
|
||||
|
@ -1,27 +1,29 @@
|
||||
/* global exports */
|
||||
"use strict";
|
||||
export var zero = BigInt("0");
|
||||
|
||||
// module Data.Unique
|
||||
var one = BigInt("1");
|
||||
|
||||
var MAX_SAFE_INTEGER = 9007199254740991;
|
||||
var uniqueSource = [];
|
||||
|
||||
function iter(i) {
|
||||
if (uniqueSource.length === i) {
|
||||
for (var j = 0; j < i; ++j) uniqueSource[j] = 0;
|
||||
uniqueSource[i] = 1;
|
||||
} else {
|
||||
if (uniqueSource[i] === MAX_SAFE_INTEGER) {
|
||||
uniqueSource[i] = 0;
|
||||
iter(i + 1);
|
||||
} else {
|
||||
uniqueSource[i]++;
|
||||
}
|
||||
}
|
||||
export function eqImpl(a) {
|
||||
return function(b) {
|
||||
return a === b;
|
||||
};
|
||||
}
|
||||
|
||||
export function newUnique() {
|
||||
iter(0);
|
||||
return uniqueSource.length === 1 ? uniqueSource[0] + "" : uniqueSource.join(",");
|
||||
};
|
||||
export function ordImpl(lt) {
|
||||
return function (eq) {
|
||||
return function (gt) {
|
||||
return function (x) {
|
||||
return function (y) {
|
||||
return x < y ? lt : x === y ? eq : gt;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function addOne(x) {
|
||||
return x + one;
|
||||
}
|
||||
|
||||
export function hashUnique(x) {
|
||||
return parseInt(BigInt.asIntN(32, x));
|
||||
}
|
@ -1,20 +1,41 @@
|
||||
module Data.Unique
|
||||
( newUnique
|
||||
, Unique
|
||||
) where
|
||||
module Data.Unique (Unique, hashUnique, newUnique) where
|
||||
|
||||
import Prelude hiding (zero)
|
||||
|
||||
import Effect (Effect)
|
||||
import Prelude (class Ord, class Eq, class Show, compare, (==))
|
||||
import Effect.Ref (Ref)
|
||||
import Effect.Ref as Ref
|
||||
import Effect.Unsafe (unsafePerformEffect)
|
||||
|
||||
newtype Unique = Unique String
|
||||
-- | An abstract unique object. Objects of type `Unique` may be compared for
|
||||
-- | equality and ordering and hashed into `Int`.
|
||||
foreign import data Unique :: Type
|
||||
|
||||
foreign import newUnique :: Effect Unique
|
||||
foreign import eqImpl :: Unique -> Unique -> Boolean
|
||||
|
||||
instance showUnique :: Show Unique where
|
||||
show (Unique a) = a
|
||||
instance Eq Unique where
|
||||
eq = eqImpl
|
||||
|
||||
instance eqUnique :: Eq Unique where
|
||||
eq (Unique a) (Unique b) = a == b
|
||||
foreign import ordImpl :: Ordering -> Ordering -> Ordering -> Unique -> Unique -> Ordering
|
||||
|
||||
instance ordUnique :: Ord Unique where
|
||||
compare (Unique a) (Unique b) = compare a b
|
||||
instance Ord Unique where
|
||||
compare = ordImpl LT EQ GT
|
||||
|
||||
foreign import addOne :: Unique -> Unique
|
||||
|
||||
foreign import zero :: Unique
|
||||
|
||||
-- | Hashes a `Unique` into an `Int`. Two `Unique`s may hash to the same value,
|
||||
-- | although in practice this is unlikely. The `Int` returned makes a good hash
|
||||
-- | key.
|
||||
foreign import hashUnique :: Unique -> Int
|
||||
|
||||
uniqSource :: Ref Unique
|
||||
uniqSource = unsafePerformEffect (Ref.new zero)
|
||||
|
||||
-- | 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 `newUnique` may be
|
||||
-- | called.
|
||||
newUnique :: Effect Unique
|
||||
newUnique = Ref.modify addOne uniqSource
|
@ -1,7 +1,7 @@
|
||||
module Test.Main where
|
||||
|
||||
import Prelude ((==), ($), (/=), discard, bind, Unit)
|
||||
import Data.Unique (newUnique)
|
||||
import Prelude
|
||||
import Data.Unique (hashUnique, newUnique)
|
||||
import Test.Assert (assert)
|
||||
import Effect (Effect)
|
||||
import Effect.Console (log)
|
||||
@ -11,5 +11,7 @@ main = do
|
||||
log "Test Data.Unique"
|
||||
a <- newUnique
|
||||
b <- newUnique
|
||||
assert $ a /= b
|
||||
assert $ a == a
|
||||
assert $ a < b
|
||||
assert $ hashUnique a == hashUnique a
|
||||
assert $ hashUnique a /= hashUnique b
|
Loading…
Reference in New Issue
Block a user