From 79f8ae4e69cd73fe2f60ea28e29b650d0f959add Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 13 Jul 2022 11:15:57 +0200 Subject: [PATCH] make Set/Dict mostly work --- crates/compiler/builtins/roc/Dict.roc | 8 +- crates/compiler/builtins/roc/Set.roc | 6 +- crates/compiler/load_internal/src/file.rs | 2 +- crates/compiler/module/src/symbol.rs | 1 + crates/compiler/test_gen/src/gen_dict.rs | 12 +- crates/compiler/test_gen/src/gen_set.rs | 135 ++++++++++++++-------- 6 files changed, 107 insertions(+), 57 deletions(-) diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 236a305644..b2fc7de943 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -2,6 +2,7 @@ interface Dict exposes [ Dict, empty, + withCapacity, single, get, walk, @@ -18,6 +19,7 @@ interface Dict imports [ Bool.{ Bool }, Result.{ Result }, + List, ] ## 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 [] +withCapacity : Nat -> Dict k v +withCapacity = \n -> @Dict (List.withCapacity n) + get : Dict k v, k -> Result v [KeyNotFound]* get = \@Dict list, needle -> when List.find list (\Pair key _ -> key == needle) is @@ -132,6 +137,7 @@ single : k, v -> Dict k v single = \key, value -> @Dict [Pair key value] + ## Returns a [List] of the dictionary's keys. keys : Dict k v -> List k keys = \@Dict list -> @@ -149,7 +155,7 @@ insertAll = \xs, @Dict ys -> # intersection : 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) |> @Dict diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index 54e348356d..d78eb6f832 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -30,7 +30,7 @@ empty = fromDict Dict.empty single : k -> Set k 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 ## 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. remove : Set k, k -> Set k remove = \@Set dict, key -> - @Set (Dict.remove key dict) + @Set (Dict.remove dict key) contains : Set k, k -> Bool contains = \set, key -> @@ -62,7 +62,7 @@ toList = \@Set dict -> fromList : List k -> Set k 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 diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 70497da80e..88d0eead2f 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -4347,7 +4347,7 @@ fn canonicalize_and_constrain<'a>( // do nothing } Vacant(vacant) => { - if name == Symbol::DICT_DICT { + if name == Symbol::DICT_DICT || name == Symbol::SET_SET { vacant.insert((false, alias)); } else if !name.is_builtin() || name.module_id() == ModuleId::ENCODE { vacant.insert((false, alias)); diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index 0f6c7980ad..d7a65f6678 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1320,6 +1320,7 @@ define_builtins! { 14 DICT_DIFFERENCE: "difference" 15 DICT_GET_LOWLEVEL: "getLowlevel" + 16 DICT_WITH_CAPACITY: "withCapacity" } 8 SET: "Set" => { 0 SET_SET: "Set" // the Set.Set type alias diff --git a/crates/compiler/test_gen/src/gen_dict.rs b/crates/compiler/test_gen/src/gen_dict.rs index 472ae54bdb..16cc9f8490 100644 --- a/crates/compiler/test_gen/src/gen_dict.rs +++ b/crates/compiler/test_gen/src/gen_dict.rs @@ -243,7 +243,7 @@ fn from_list_with_fold_simple() { main = Dict.values myDict "# ), - RocList::from_slice(&[2, 3, 1]), + RocList::from_slice(&[1, 2, 3]), RocList ); } @@ -273,8 +273,8 @@ fn from_list_with_fold_reallocates() { "# ), 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, - 23 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24 ]), RocList ); @@ -299,7 +299,7 @@ fn small_str_keys() { 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 ); } @@ -324,8 +324,8 @@ fn big_str_keys() { ), RocList::from_slice(&[ 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("to corporate strategy foster collaborative thinking to"), ]), RocList ); @@ -351,8 +351,8 @@ fn big_str_values() { ), RocList::from_slice(&[ 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("to corporate strategy foster collaborative thinking to"), ]), RocList ); diff --git a/crates/compiler/test_gen/src/gen_set.rs b/crates/compiler/test_gen/src/gen_set.rs index e2e091b71c..e1678339e0 100644 --- a/crates/compiler/test_gen/src/gen_set.rs +++ b/crates/compiler/test_gen/src/gen_set.rs @@ -18,7 +18,9 @@ fn empty_len() { assert_evals_to!( indoc!( r#" - Set.len Set.empty + app "set" imports [ Set ] provides [main] to "./platform" + + main = Set.len Set.empty "# ), 0, @@ -32,7 +34,9 @@ fn single_len() { assert_evals_to!( indoc!( r#" - Set.len (Set.single 42) + app "set" imports [ Set ] provides [main] to "./platform" + + main = Set.len (Set.single 42) "# ), 1, @@ -46,7 +50,9 @@ fn single_to_list() { assert_evals_to!( indoc!( r#" - Set.toList (Set.single 42) + app "set" imports [ Set ] provides [main] to "./platform" + + main = Set.toList (Set.single 42) "# ), RocList::from_slice(&[42]), @@ -56,7 +62,9 @@ fn single_to_list() { assert_evals_to!( indoc!( r#" - Set.toList (Set.single 1) + app "set" imports [ Set ] provides [main] to "./platform" + + main = Set.toList (Set.single 1) "# ), RocList::from_slice(&[1]), @@ -66,7 +74,9 @@ fn single_to_list() { assert_evals_to!( indoc!( 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]), @@ -80,11 +90,14 @@ fn insert() { assert_evals_to!( indoc!( r#" - Set.empty - |> Set.insert 0 - |> Set.insert 1 - |> Set.insert 2 - |> Set.toList + app "set" imports [ Set ] provides [main] to "./platform" + + main = + Set.empty + |> Set.insert 0 + |> Set.insert 1 + |> Set.insert 2 + |> Set.toList "# ), RocList::from_slice(&[0, 1, 2]), @@ -98,12 +111,15 @@ fn remove() { assert_evals_to!( indoc!( r#" - Set.empty - |> Set.insert 0 - |> Set.insert 1 - |> Set.remove 1 - |> Set.remove 2 - |> Set.toList + app "set" imports [ Set ] provides [main] to "./platform" + + main = + Set.empty + |> Set.insert 0 + |> Set.insert 1 + |> Set.remove 1 + |> Set.remove 2 + |> Set.toList "# ), RocList::from_slice(&[0]), @@ -117,17 +133,20 @@ fn union() { assert_evals_to!( indoc!( r#" - set1 : Set I64 + app "set" imports [ Set ] provides [main] to "./platform" + + set1 : Set.Set I64 set1 = Set.fromList [1,2] - set2 : Set I64 + set2 : Set.Set I64 set2 = Set.fromList [1,3,4] - Set.union set1 set2 - |> Set.toList + main = + Set.union set1 set2 + |> Set.toList "# ), - RocList::from_slice(&[4, 2, 3, 1]), + RocList::from_slice(&[1, 2, 3, 4]), RocList ); } @@ -138,14 +157,17 @@ fn difference() { assert_evals_to!( indoc!( r#" - set1 : Set I64 + app "set" imports [ Set ] provides [main] to "./platform" + + set1 : Set.Set I64 set1 = Set.fromList [1,2] - set2 : Set I64 + set2 : Set.Set I64 set2 = Set.fromList [1,3,4] - Set.difference set1 set2 - |> Set.toList + main = + Set.difference set1 set2 + |> Set.toList "# ), RocList::from_slice(&[2]), @@ -159,14 +181,17 @@ fn intersection() { assert_evals_to!( indoc!( r#" - set1 : Set I64 + app "set" imports [ Set ] provides [main] to "./platform" + + set1 : Set.Set I64 set1 = Set.fromList [1,2] - set2 : Set I64 + set2 : Set.Set I64 set2 = Set.fromList [1,3,4] - Set.intersection set1 set2 - |> Set.toList + main = + Set.intersection set1 set2 + |> Set.toList "# ), RocList::from_slice(&[1]), @@ -180,7 +205,9 @@ fn walk_sum() { assert_evals_to!( indoc!( 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, @@ -194,7 +221,9 @@ fn contains() { assert_evals_to!( indoc!( 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, @@ -204,7 +233,9 @@ fn contains() { assert_evals_to!( indoc!( 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, @@ -218,24 +249,30 @@ fn from_list() { assert_evals_to!( indoc!( r#" - [1,2,2,3,1,4] - |> Set.fromList - |> Set.toList + app "set" imports [ Set ] provides [main] to "./platform" + + main = + [1,2,2,3,1,4] + |> Set.fromList + |> Set.toList "# ), - RocList::from_slice(&[4, 2, 3, 1]), + RocList::from_slice(&[1, 2, 3, 4]), RocList ); assert_evals_to!( indoc!( r#" + app "set" imports [ Set ] provides [main] to "./platform" + empty : List I64 empty = [] - empty - |> Set.fromList - |> Set.toList + main = + empty + |> Set.fromList + |> Set.toList "# ), RocList::::default(), @@ -249,9 +286,12 @@ fn from_list_void() { assert_evals_to!( indoc!( r#" - [] - |> Set.fromList - |> Set.toList + app "set" imports [ Set ] provides [main] to "./platform" + + main = + [] + |> Set.fromList + |> Set.toList "# ), RocList::::default(), @@ -265,13 +305,16 @@ fn from_list_result() { assert_evals_to!( indoc!( r#" + app "set" imports [ Set ] provides [main] to "./platform" + x : Result Str {} x = Ok "foo" - [x] - |> Set.fromList - |> Set.toList - |> List.len + main = + [x] + |> Set.fromList + |> Set.toList + |> List.len "# ), 1,