mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
make Set/Dict mostly work
This commit is contained in:
parent
4d33e32078
commit
79f8ae4e69
6 changed files with 107 additions and 57 deletions
|
@ -2,6 +2,7 @@ interface Dict
|
||||||
exposes [
|
exposes [
|
||||||
Dict,
|
Dict,
|
||||||
empty,
|
empty,
|
||||||
|
withCapacity,
|
||||||
single,
|
single,
|
||||||
get,
|
get,
|
||||||
walk,
|
walk,
|
||||||
|
@ -18,6 +19,7 @@ interface Dict
|
||||||
imports [
|
imports [
|
||||||
Bool.{ Bool },
|
Bool.{ Bool },
|
||||||
Result.{ Result },
|
Result.{ Result },
|
||||||
|
List,
|
||||||
]
|
]
|
||||||
|
|
||||||
## A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you can associate keys with values.
|
## A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you can associate keys with values.
|
||||||
|
@ -74,6 +76,9 @@ Dict k v := List [Pair k v]
|
||||||
empty : Dict k v
|
empty : Dict k v
|
||||||
empty = @Dict []
|
empty = @Dict []
|
||||||
|
|
||||||
|
withCapacity : Nat -> Dict k v
|
||||||
|
withCapacity = \n -> @Dict (List.withCapacity n)
|
||||||
|
|
||||||
get : Dict k v, k -> Result v [KeyNotFound]*
|
get : Dict k v, k -> Result v [KeyNotFound]*
|
||||||
get = \@Dict list, needle ->
|
get = \@Dict list, needle ->
|
||||||
when List.find list (\Pair key _ -> key == needle) is
|
when List.find list (\Pair key _ -> key == needle) is
|
||||||
|
@ -132,6 +137,7 @@ single : k, v -> Dict k v
|
||||||
single = \key, value ->
|
single = \key, value ->
|
||||||
@Dict [Pair key value]
|
@Dict [Pair key value]
|
||||||
|
|
||||||
|
|
||||||
## Returns a [List] of the dictionary's keys.
|
## Returns a [List] of the dictionary's keys.
|
||||||
keys : Dict k v -> List k
|
keys : Dict k v -> List k
|
||||||
keys = \@Dict list ->
|
keys = \@Dict list ->
|
||||||
|
@ -149,7 +155,7 @@ insertAll = \xs, @Dict ys ->
|
||||||
|
|
||||||
# intersection : Dict k v, Dict k v -> Dict k v
|
# intersection : Dict k v, Dict k v -> Dict k v
|
||||||
keepShared : Dict k v, Dict k v -> Dict k v
|
keepShared : Dict k v, Dict k v -> Dict k v
|
||||||
keepShared = \Dict xs, ys ->
|
keepShared = \@Dict xs, ys ->
|
||||||
List.keepIf xs (\Pair k _ -> Dict.contains ys k)
|
List.keepIf xs (\Pair k _ -> Dict.contains ys k)
|
||||||
|> @Dict
|
|> @Dict
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ empty = fromDict Dict.empty
|
||||||
|
|
||||||
single : k -> Set k
|
single : k -> Set k
|
||||||
single = \key ->
|
single = \key ->
|
||||||
Dict.single key {}
|
@Set (Dict.single key {})
|
||||||
|
|
||||||
## Make sure never to insert a *NaN* to a [Set]! Because *NaN* is defined to be
|
## 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
|
## unequal to *NaN*, adding a *NaN* results in an entry that can never be
|
||||||
|
@ -48,7 +48,7 @@ len = \@Set dict ->
|
||||||
## Drops the given element from the set.
|
## Drops the given element from the set.
|
||||||
remove : Set k, k -> Set k
|
remove : Set k, k -> Set k
|
||||||
remove = \@Set dict, key ->
|
remove = \@Set dict, key ->
|
||||||
@Set (Dict.remove key dict)
|
@Set (Dict.remove dict key)
|
||||||
|
|
||||||
contains : Set k, k -> Bool
|
contains : Set k, k -> Bool
|
||||||
contains = \set, key ->
|
contains = \set, key ->
|
||||||
|
@ -62,7 +62,7 @@ toList = \@Set dict ->
|
||||||
|
|
||||||
fromList : List k -> Set k
|
fromList : List k -> Set k
|
||||||
fromList = \list ->
|
fromList = \list ->
|
||||||
initial = List.withCapacity (List.len list)
|
initial = @Set (Dict.withCapacity (List.len list))
|
||||||
|
|
||||||
List.walk list initial \set, key -> Set.insert set key
|
List.walk list initial \set, key -> Set.insert set key
|
||||||
|
|
||||||
|
|
|
@ -4347,7 +4347,7 @@ fn canonicalize_and_constrain<'a>(
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
Vacant(vacant) => {
|
Vacant(vacant) => {
|
||||||
if name == Symbol::DICT_DICT {
|
if name == Symbol::DICT_DICT || name == Symbol::SET_SET {
|
||||||
vacant.insert((false, alias));
|
vacant.insert((false, alias));
|
||||||
} else if !name.is_builtin() || name.module_id() == ModuleId::ENCODE {
|
} else if !name.is_builtin() || name.module_id() == ModuleId::ENCODE {
|
||||||
vacant.insert((false, alias));
|
vacant.insert((false, alias));
|
||||||
|
|
|
@ -1320,6 +1320,7 @@ define_builtins! {
|
||||||
14 DICT_DIFFERENCE: "difference"
|
14 DICT_DIFFERENCE: "difference"
|
||||||
|
|
||||||
15 DICT_GET_LOWLEVEL: "getLowlevel"
|
15 DICT_GET_LOWLEVEL: "getLowlevel"
|
||||||
|
16 DICT_WITH_CAPACITY: "withCapacity"
|
||||||
}
|
}
|
||||||
8 SET: "Set" => {
|
8 SET: "Set" => {
|
||||||
0 SET_SET: "Set" // the Set.Set type alias
|
0 SET_SET: "Set" // the Set.Set type alias
|
||||||
|
|
|
@ -243,7 +243,7 @@ fn from_list_with_fold_simple() {
|
||||||
main = Dict.values myDict
|
main = Dict.values myDict
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[2, 3, 1]),
|
RocList::from_slice(&[1, 2, 3]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -273,8 +273,8 @@ fn from_list_with_fold_reallocates() {
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[
|
RocList::from_slice(&[
|
||||||
4, 5, 20, 0, 7, 3, 1, 21, 10, 6, 13, 9, 14, 19, 2, 15, 12, 17, 16, 18, 22, 8, 11, 24,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
23
|
24
|
||||||
]),
|
]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -299,7 +299,7 @@ fn small_str_keys() {
|
||||||
main = Dict.keys myDict
|
main = Dict.keys myDict
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[RocStr::from("c"), RocStr::from("a"), RocStr::from("b"),],),
|
RocList::from_slice(&["a".into(), "b".into(), "c".into(),],),
|
||||||
RocList<RocStr>
|
RocList<RocStr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -324,8 +324,8 @@ fn big_str_keys() {
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[
|
RocList::from_slice(&[
|
||||||
RocStr::from("Leverage agile frameworks to provide a robust"),
|
RocStr::from("Leverage agile frameworks to provide a robust"),
|
||||||
RocStr::from("to corporate strategy foster collaborative thinking to"),
|
|
||||||
RocStr::from("synopsis for high level overviews. Iterative approaches"),
|
RocStr::from("synopsis for high level overviews. Iterative approaches"),
|
||||||
|
RocStr::from("to corporate strategy foster collaborative thinking to"),
|
||||||
]),
|
]),
|
||||||
RocList<RocStr>
|
RocList<RocStr>
|
||||||
);
|
);
|
||||||
|
@ -351,8 +351,8 @@ fn big_str_values() {
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[
|
RocList::from_slice(&[
|
||||||
RocStr::from("Leverage agile frameworks to provide a robust"),
|
RocStr::from("Leverage agile frameworks to provide a robust"),
|
||||||
RocStr::from("to corporate strategy foster collaborative thinking to"),
|
|
||||||
RocStr::from("synopsis for high level overviews. Iterative approaches"),
|
RocStr::from("synopsis for high level overviews. Iterative approaches"),
|
||||||
|
RocStr::from("to corporate strategy foster collaborative thinking to"),
|
||||||
]),
|
]),
|
||||||
RocList<RocStr>
|
RocList<RocStr>
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,7 +18,9 @@ fn empty_len() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.len Set.empty
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.len Set.empty
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
0,
|
0,
|
||||||
|
@ -32,7 +34,9 @@ fn single_len() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.len (Set.single 42)
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.len (Set.single 42)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
1,
|
1,
|
||||||
|
@ -46,7 +50,9 @@ fn single_to_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.toList (Set.single 42)
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.toList (Set.single 42)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[42]),
|
RocList::from_slice(&[42]),
|
||||||
|
@ -56,7 +62,9 @@ fn single_to_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.toList (Set.single 1)
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.toList (Set.single 1)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[1]),
|
RocList::from_slice(&[1]),
|
||||||
|
@ -66,7 +74,9 @@ fn single_to_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.toList (Set.single 1.0)
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.toList (Set.single 1.0)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[1.0]),
|
RocList::from_slice(&[1.0]),
|
||||||
|
@ -80,6 +90,9 @@ fn insert() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
Set.empty
|
Set.empty
|
||||||
|> Set.insert 0
|
|> Set.insert 0
|
||||||
|> Set.insert 1
|
|> Set.insert 1
|
||||||
|
@ -98,6 +111,9 @@ fn remove() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
Set.empty
|
Set.empty
|
||||||
|> Set.insert 0
|
|> Set.insert 0
|
||||||
|> Set.insert 1
|
|> Set.insert 1
|
||||||
|
@ -117,17 +133,20 @@ fn union() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
set1 : Set I64
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
set1 : Set.Set I64
|
||||||
set1 = Set.fromList [1,2]
|
set1 = Set.fromList [1,2]
|
||||||
|
|
||||||
set2 : Set I64
|
set2 : Set.Set I64
|
||||||
set2 = Set.fromList [1,3,4]
|
set2 = Set.fromList [1,3,4]
|
||||||
|
|
||||||
|
main =
|
||||||
Set.union set1 set2
|
Set.union set1 set2
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[4, 2, 3, 1]),
|
RocList::from_slice(&[1, 2, 3, 4]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -138,12 +157,15 @@ fn difference() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
set1 : Set I64
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
set1 : Set.Set I64
|
||||||
set1 = Set.fromList [1,2]
|
set1 = Set.fromList [1,2]
|
||||||
|
|
||||||
set2 : Set I64
|
set2 : Set.Set I64
|
||||||
set2 = Set.fromList [1,3,4]
|
set2 = Set.fromList [1,3,4]
|
||||||
|
|
||||||
|
main =
|
||||||
Set.difference set1 set2
|
Set.difference set1 set2
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
"#
|
"#
|
||||||
|
@ -159,12 +181,15 @@ fn intersection() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
set1 : Set I64
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
set1 : Set.Set I64
|
||||||
set1 = Set.fromList [1,2]
|
set1 = Set.fromList [1,2]
|
||||||
|
|
||||||
set2 : Set I64
|
set2 : Set.Set I64
|
||||||
set2 = Set.fromList [1,3,4]
|
set2 = Set.fromList [1,3,4]
|
||||||
|
|
||||||
|
main =
|
||||||
Set.intersection set1 set2
|
Set.intersection set1 set2
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
"#
|
"#
|
||||||
|
@ -180,7 +205,9 @@ fn walk_sum() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.walk (Set.fromList [1,2,3]) 0 (\x, y -> x + y)
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.walk (Set.fromList [1,2,3]) 0 (\x, y -> x + y)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
6,
|
6,
|
||||||
|
@ -194,7 +221,9 @@ fn contains() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.contains (Set.fromList [1,3,4]) 4
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.contains (Set.fromList [1,3,4]) 4
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
|
@ -204,7 +233,9 @@ fn contains() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Set.contains (Set.fromList [1,3,4]) 2
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main = Set.contains (Set.fromList [1,3,4]) 2
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
false,
|
false,
|
||||||
|
@ -218,21 +249,27 @@ fn from_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
[1,2,2,3,1,4]
|
[1,2,2,3,1,4]
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[4, 2, 3, 1]),
|
RocList::from_slice(&[1, 2, 3, 4]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
empty : List I64
|
empty : List I64
|
||||||
empty = []
|
empty = []
|
||||||
|
|
||||||
|
main =
|
||||||
empty
|
empty
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
|
@ -249,6 +286,9 @@ fn from_list_void() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
[]
|
[]
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
|
@ -265,9 +305,12 @@ fn from_list_result() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
app "set" imports [ Set ] provides [main] to "./platform"
|
||||||
|
|
||||||
x : Result Str {}
|
x : Result Str {}
|
||||||
x = Ok "foo"
|
x = Ok "foo"
|
||||||
|
|
||||||
|
main =
|
||||||
[x]
|
[x]
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue