Merge pull request #4696 from roc-lang/hash-nat

add the ability to hash Nats
This commit is contained in:
Ayaz 2022-12-05 20:15:21 -06:00 committed by GitHub
commit 8ae8857125
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 20 deletions

View file

@ -821,6 +821,13 @@ expect
|> len
|> Bool.isEq 0
# Makes sure a Dict with Nat keys works
expect
empty
|> insert 7nat "Testing"
|> get 7
|> Bool.isEq (Ok "Testing")
# We have decided not to expose the standard roc hashing algorithm.
# This is to avoid external dependence and the need for versioning.
# The current implementation is a form of [Wyhash final3](https://github.com/wangyi-fudan/wyhash/blob/a5995b98ebfa7bd38bfadc0919326d2e7aabb805/wyhash.h).

View file

@ -14,14 +14,16 @@ interface Hash
hashI32,
hashI64,
hashI128,
hashNat,
complete,
hashStrBytes,
hashList,
hashUnordered,
] imports [
Bool.{ isEq },
List,
Str,
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128 },
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, Nat },
]
## A value that can hashed.
@ -88,6 +90,21 @@ hashI64 = \hasher, n -> addU64 hasher (Num.toU64 n)
hashI128 : a, I128 -> a | a has Hasher
hashI128 = \hasher, n -> addU128 hasher (Num.toU128 n)
## Adds a single Nat to a hasher.
hashNat : a, Nat -> a | a has Hasher
hashNat = \hasher, n ->
isPlatform32bit =
x : Nat
x = 0xffff_ffff
y = Num.addWrap x 1
y == 0
if isPlatform32bit then
addU32 hasher (Num.toU32 n)
else
addU64 hasher (Num.toU64 n)
## Adds a container of [Hash]able elements to a [Hasher] by hashing each element.
## The container is iterated using the walk method passed in.
## The order of the elements does not affect the final hash.

View file

@ -174,6 +174,9 @@ const fn num_symbol_to_hash_lambda(symbol: Symbol) -> Option<FlatHash> {
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => {
Some(SingleLambdaSetImmediate(Symbol::HASH_HASH_I128))
}
Symbol::NUM_NAT | Symbol::NUM_NATURAL => {
Some(SingleLambdaSetImmediate(Symbol::HASH_HASH_NAT))
}
_ => None,
}
}

View file

@ -1522,10 +1522,11 @@ define_builtins! {
11 HASH_HASH_I32: "hashI32"
12 HASH_HASH_I64: "hashI64"
13 HASH_HASH_I128: "hashI128"
14 HASH_COMPLETE: "complete"
15 HASH_HASH_STR_BYTES: "hashStrBytes"
16 HASH_HASH_LIST: "hashList"
17 HASH_HASH_UNORDERED: "hashUnordered"
14 HASH_HASH_NAT: "hashNat"
15 HASH_COMPLETE: "complete"
16 HASH_HASH_STR_BYTES: "hashStrBytes"
17 HASH_HASH_LIST: "hashList"
18 HASH_HASH_UNORDERED: "hashUnordered"
}
14 JSON: "Json" => {
0 JSON_JSON: "Json"

View file

@ -1,22 +1,22 @@
procedure Dict.1 ():
let Dict.518 : List {[], []} = Array [];
let Dict.525 : U64 = 0i64;
let Dict.526 : U64 = 8i64;
let Dict.519 : List U64 = CallByName List.11 Dict.525 Dict.526;
let Dict.522 : I8 = CallByName Dict.34;
let Dict.523 : U64 = 8i64;
let Dict.520 : List I8 = CallByName List.11 Dict.522 Dict.523;
let Dict.521 : U64 = 0i64;
let Dict.517 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.518, Dict.519, Dict.520, Dict.521};
ret Dict.517;
let Dict.520 : List {[], []} = Array [];
let Dict.527 : U64 = 0i64;
let Dict.528 : U64 = 8i64;
let Dict.521 : List U64 = CallByName List.11 Dict.527 Dict.528;
let Dict.524 : I8 = CallByName Dict.34;
let Dict.525 : U64 = 8i64;
let Dict.522 : List I8 = CallByName List.11 Dict.524 Dict.525;
let Dict.523 : U64 = 0i64;
let Dict.519 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.520, Dict.521, Dict.522, Dict.523};
ret Dict.519;
procedure Dict.34 ():
let Dict.524 : I8 = -128i64;
ret Dict.524;
let Dict.526 : I8 = -128i64;
ret Dict.526;
procedure Dict.4 (Dict.505):
let Dict.85 : U64 = StructAtIndex 3 Dict.505;
dec Dict.505;
procedure Dict.4 (Dict.507):
let Dict.85 : U64 = StructAtIndex 3 Dict.507;
dec Dict.507;
ret Dict.85;
procedure List.11 (List.113, List.114):