mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-14 07:29:02 +03:00
add Set implementation
This commit is contained in:
parent
cb08dca6f1
commit
02824e92fe
@ -96,7 +96,9 @@ Dict k v := {
|
||||
dataIndices : List Nat,
|
||||
data : List (T k v),
|
||||
size : Nat,
|
||||
} | k has Hash & Eq
|
||||
}
|
||||
# TODO: re-add type definition one #4408 is fixed
|
||||
# | k has Hash & Eq
|
||||
|
||||
## Return an empty dictionary.
|
||||
empty : Dict k v | k has Hash & Eq
|
||||
@ -486,8 +488,7 @@ removeAll : Dict k v, Dict k v -> Dict k v | k has Hash & Eq
|
||||
removeAll = \xs, ys ->
|
||||
walk ys xs (\state, k, _ -> remove state k)
|
||||
|
||||
# TODO: re-add type definition one #4408 is fixed
|
||||
# updateDataIndex : Dict k v, k, Nat -> Dict k v | k has Hash & Eq
|
||||
updateDataIndex : Dict k v, k, Nat -> Dict k v | k has Hash & Eq
|
||||
updateDataIndex = \@Dict { metadata, dataIndices, data, size }, key, dataIndex ->
|
||||
hashKey =
|
||||
createLowLevelHasher {}
|
||||
@ -514,8 +515,8 @@ insertNotFoundHelper : Dict k v, k, v, U64, I8 -> Dict k v
|
||||
insertNotFoundHelper = \@Dict { metadata, dataIndices, data, size }, key, value, h1Key, h2Key ->
|
||||
probe = newProbe h1Key (div8 (List.len metadata))
|
||||
index = nextEmptyOrDeletedHelper metadata probe 0
|
||||
dataIndex = List.len data
|
||||
nextData = List.append data (T key value)
|
||||
dataIndex = List.len data - 1
|
||||
|
||||
@Dict {
|
||||
metadata: List.set metadata index h2Key,
|
||||
|
@ -14,32 +14,40 @@ interface Set
|
||||
intersection,
|
||||
difference,
|
||||
]
|
||||
imports [List, Bool.{ Bool, Eq }, Dict.{ Dict }, Num.{ Nat }]
|
||||
imports [
|
||||
List,
|
||||
Bool.{ Bool, Eq },
|
||||
Dict.{ Dict },
|
||||
Num.{ Nat },
|
||||
Hash.{ Hasher, Hash },
|
||||
]
|
||||
|
||||
Set k := Dict.Dict k {} has [Eq]
|
||||
Set k := Dict.Dict k {}
|
||||
# TODO: re-add type definition one #4408 is fixed
|
||||
# | k has Hash & Eq
|
||||
has [
|
||||
Eq {
|
||||
isEq,
|
||||
},
|
||||
]
|
||||
|
||||
fromDict : Dict k {} -> Set k
|
||||
fromDict = \dict -> @Set dict
|
||||
|
||||
toDict : Set k -> Dict k {}
|
||||
toDict = \@Set dict -> dict
|
||||
isEq : Set k, Set k -> Bool | k has Hash & Eq
|
||||
isEq = \_, _ -> Bool.true
|
||||
|
||||
## An empty set.
|
||||
empty : Set k
|
||||
empty = fromDict Dict.empty
|
||||
empty : Set k | k has Hash & Eq
|
||||
empty = @Set Dict.empty
|
||||
|
||||
single : k -> Set k
|
||||
single : k -> Set k | k has Hash & Eq
|
||||
single = \key ->
|
||||
@Set (Dict.single key {})
|
||||
Dict.single key {} |> @Set
|
||||
|
||||
## Make sure never to insert a *NaN* to a [Set]! Because *NaN* is defined to be
|
||||
## unequal to *NaN*, adding a *NaN* results in an entry that can never be
|
||||
## retrieved or removed from the [Set].
|
||||
insert : Set k, k -> Set k | k has Eq
|
||||
insert : Set k, k -> Set k | k has Hash & Eq
|
||||
insert = \@Set dict, key ->
|
||||
dict
|
||||
|> Dict.insert key {}
|
||||
|> @Set
|
||||
Dict.insert dict key {} |> @Set
|
||||
|
||||
# Inserting a duplicate key has no effect.
|
||||
expect
|
||||
@ -58,7 +66,7 @@ expect
|
||||
|
||||
expected == actual
|
||||
|
||||
len : Set k -> Nat
|
||||
len : Set k -> Nat | k has Hash & Eq
|
||||
len = \@Set dict ->
|
||||
Dict.len dict
|
||||
|
||||
@ -75,38 +83,36 @@ expect
|
||||
actual == 3
|
||||
|
||||
## Drops the given element from the set.
|
||||
remove : Set k, k -> Set k | k has Eq
|
||||
remove : Set k, k -> Set k | k has Hash & Eq
|
||||
remove = \@Set dict, key ->
|
||||
@Set (Dict.remove dict key)
|
||||
Dict.remove dict key |> @Set
|
||||
|
||||
contains : Set k, k -> Bool | k has Eq
|
||||
contains = \set, key ->
|
||||
set
|
||||
|> Set.toDict
|
||||
|> Dict.contains key
|
||||
contains : Set k, k -> Bool | k has Hash & Eq
|
||||
contains = \@Set dict, key ->
|
||||
Dict.contains dict key
|
||||
|
||||
toList : Set k -> List k
|
||||
toList : Set k -> List k | k has Hash & Eq
|
||||
toList = \@Set dict ->
|
||||
Dict.keys dict
|
||||
|
||||
fromList : List k -> Set k | k has Eq
|
||||
fromList : List k -> Set k | k has Hash & Eq
|
||||
fromList = \list ->
|
||||
initial = @Set (Dict.withCapacity (List.len list))
|
||||
|
||||
List.walk list initial \set, key -> Set.insert set key
|
||||
|
||||
union : Set k, Set k -> Set k | k has Eq
|
||||
union : Set k, Set k -> Set k | k has Hash & Eq
|
||||
union = \@Set dict1, @Set dict2 ->
|
||||
@Set (Dict.insertAll dict1 dict2)
|
||||
Dict.insertAll dict1 dict2 |> @Set
|
||||
|
||||
intersection : Set k, Set k -> Set k | k has Eq
|
||||
intersection : Set k, Set k -> Set k | k has Hash & Eq
|
||||
intersection = \@Set dict1, @Set dict2 ->
|
||||
@Set (Dict.keepShared dict1 dict2)
|
||||
Dict.keepShared dict1 dict2 |> @Set
|
||||
|
||||
difference : Set k, Set k -> Set k | k has Eq
|
||||
difference : Set k, Set k -> Set k | k has Hash & Eq
|
||||
difference = \@Set dict1, @Set dict2 ->
|
||||
@Set (Dict.removeAll dict1 dict2)
|
||||
Dict.removeAll dict1 dict2 |> @Set
|
||||
|
||||
walk : Set k, state, (state, k -> state) -> state
|
||||
walk = \set, state, step ->
|
||||
Dict.walk (Set.toDict set) state (\s, k, _ -> step s k)
|
||||
walk : Set k, state, (state, k -> state) -> state | k has Hash & Eq
|
||||
walk = \@Set dict, state, step ->
|
||||
Dict.walk dict state (\s, k, _ -> step s k)
|
||||
|
Loading…
Reference in New Issue
Block a user