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 |> len
|> Bool.isEq 0 |> 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. # We have decided not to expose the standard roc hashing algorithm.
# This is to avoid external dependence and the need for versioning. # 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). # 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, hashI32,
hashI64, hashI64,
hashI128, hashI128,
hashNat,
complete, complete,
hashStrBytes, hashStrBytes,
hashList, hashList,
hashUnordered, hashUnordered,
] imports [ ] imports [
Bool.{ isEq },
List, List,
Str, 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. ## 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 : a, I128 -> a | a has Hasher
hashI128 = \hasher, n -> addU128 hasher (Num.toU128 n) 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. ## 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 container is iterated using the walk method passed in.
## The order of the elements does not affect the final hash. ## 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 => { Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => {
Some(SingleLambdaSetImmediate(Symbol::HASH_HASH_I128)) Some(SingleLambdaSetImmediate(Symbol::HASH_HASH_I128))
} }
Symbol::NUM_NAT | Symbol::NUM_NATURAL => {
Some(SingleLambdaSetImmediate(Symbol::HASH_HASH_NAT))
}
_ => None, _ => None,
} }
} }

View file

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

View file

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