mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
add Hash and Eq to Dict and Set
This commit is contained in:
parent
9b58c0fb9c
commit
877be563ba
2 changed files with 121 additions and 2 deletions
|
@ -98,6 +98,30 @@ Dict k v := {
|
|||
data : List (T k v),
|
||||
size : Nat,
|
||||
} | k has Hash & Eq
|
||||
has [
|
||||
Eq {
|
||||
isEq,
|
||||
},
|
||||
Hash {
|
||||
hash: hashDict,
|
||||
},
|
||||
]
|
||||
|
||||
isEq : Dict k v, Dict k v -> Bool | k has Hash & Eq, v has Eq
|
||||
isEq = \xs, ys ->
|
||||
if len xs != len ys then
|
||||
Bool.false
|
||||
else
|
||||
walkUntil xs Bool.true \_, k, xVal ->
|
||||
when get ys k is
|
||||
Ok yVal if yVal == xVal ->
|
||||
Continue Bool.true
|
||||
|
||||
_ ->
|
||||
Break Bool.false
|
||||
|
||||
hashDict : hasher, Dict k v -> hasher | k has Hash & Eq, v has Hash, hasher has Hasher
|
||||
hashDict = \hasher, dict -> Hash.hashUnordered hasher (toList dict) List.walk
|
||||
|
||||
## Return an empty dictionary.
|
||||
## ```
|
||||
|
@ -747,6 +771,71 @@ expect
|
|||
|
||||
val == Ok "bar"
|
||||
|
||||
expect
|
||||
dict1 =
|
||||
empty {}
|
||||
|> insert 1 "bar"
|
||||
|> insert 2 "baz"
|
||||
|
||||
dict2 =
|
||||
empty {}
|
||||
|> insert 2 "baz"
|
||||
|> insert 1 "bar"
|
||||
|
||||
dict1 == dict2
|
||||
|
||||
expect
|
||||
dict1 =
|
||||
empty {}
|
||||
|> insert 1 "bar"
|
||||
|> insert 2 "baz"
|
||||
|
||||
dict2 =
|
||||
empty {}
|
||||
|> insert 1 "bar"
|
||||
|> insert 2 "baz!"
|
||||
|
||||
dict1 != dict2
|
||||
|
||||
expect
|
||||
inner1 =
|
||||
empty {}
|
||||
|> insert 1 "bar"
|
||||
|> insert 2 "baz"
|
||||
|
||||
inner2 =
|
||||
empty {}
|
||||
|> insert 2 "baz"
|
||||
|> insert 1 "bar"
|
||||
|
||||
outer =
|
||||
empty {}
|
||||
|> insert inner1 "wrong"
|
||||
|> insert inner2 "right"
|
||||
|
||||
get outer inner1 == Ok "right"
|
||||
|
||||
expect
|
||||
inner1 =
|
||||
empty {}
|
||||
|> insert 1 "bar"
|
||||
|> insert 2 "baz"
|
||||
|
||||
inner2 =
|
||||
empty {}
|
||||
|> insert 2 "baz"
|
||||
|> insert 1 "bar"
|
||||
|
||||
outer1 =
|
||||
empty {}
|
||||
|> insert inner1 "val"
|
||||
|
||||
outer2 =
|
||||
empty {}
|
||||
|> insert inner2 "val"
|
||||
|
||||
outer1 == outer2
|
||||
|
||||
expect
|
||||
val =
|
||||
empty {}
|
||||
|
|
|
@ -20,7 +20,7 @@ interface Set
|
|||
Bool.{ Bool, Eq },
|
||||
Dict.{ Dict },
|
||||
Num.{ Nat },
|
||||
Hash.{ Hash },
|
||||
Hash.{ Hash, Hasher },
|
||||
]
|
||||
|
||||
# We should have this line above the next has.
|
||||
|
@ -28,11 +28,14 @@ interface Set
|
|||
# | k has Hash & Eq
|
||||
## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
|
||||
## type which stores a collection of unique values, without any ordering
|
||||
Set k := Dict.Dict k {}
|
||||
Set k := Dict.Dict k {} | k has Hash & Eq
|
||||
has [
|
||||
Eq {
|
||||
isEq,
|
||||
},
|
||||
Hash {
|
||||
hash: hashSet,
|
||||
},
|
||||
]
|
||||
|
||||
isEq : Set k, Set k -> Bool | k has Hash & Eq
|
||||
|
@ -46,6 +49,9 @@ isEq = \xs, ys ->
|
|||
else
|
||||
Break Bool.false
|
||||
|
||||
hashSet : hasher, Set k -> hasher | k has Hash & Eq, hasher has Hasher
|
||||
hashSet = \hasher, @Set inner -> Hash.hash hasher inner
|
||||
|
||||
## Creates a new empty `Set`.
|
||||
## ```
|
||||
## emptySet = Set.empty {}
|
||||
|
@ -353,3 +359,27 @@ expect
|
|||
|> insert 9
|
||||
|
||||
x == fromList (toList x)
|
||||
|
||||
# TODO: This test that puts a Set in a Set fails to unify.
|
||||
# expect
|
||||
# orderOne : Set Nat
|
||||
# orderOne =
|
||||
# single 1
|
||||
# |> insert 2
|
||||
|
||||
# orderTwo : Set Nat
|
||||
# orderTwo =
|
||||
# single 2
|
||||
# |> insert 1
|
||||
|
||||
# wrapperOne : Set (Set Nat)
|
||||
# wrapperOne =
|
||||
# single orderOne
|
||||
# |> insert orderTwo
|
||||
|
||||
# wrapperTwo : Set (Set Nat)
|
||||
# wrapperTwo =
|
||||
# single orderTwo
|
||||
# |> insert orderOne
|
||||
|
||||
# wrapperOne == wrapperTwo
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue