From 3f50f78ebaccdf02e2f08c7ee12d5594f9b2ac44 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Sun, 3 Dec 2023 18:39:02 -0800 Subject: [PATCH] update tests and Dict.keepShared semantics --- crates/compiler/builtins/roc/Dict.roc | 24 ++++++++++++++---------- crates/compiler/test_gen/src/gen_dict.rs | 6 +++--- crates/compiler/test_gen/src/gen_set.rs | 2 +- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index d48118d12d..84285d7fc8 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -629,23 +629,26 @@ insertAll = \xs, ys -> ## Combine two dictionaries by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)) ## of all the key-value pairs. This means that we keep only those pairs -## that are in both dictionaries. Note that where there are pairs with -## the same key, the value contained in the first input will be retained, -## and the value in the second input will be removed. +## that are in both dictionaries. Both the key and value must match to be kept. ## ``` ## first = ## Dict.single 1 "Keep Me" ## |> Dict.insert 2 "And Me" +## |> Dict.insert 3 "Not this one" ## ## second = ## Dict.single 1 "Keep Me" ## |> Dict.insert 2 "And Me" -## |> Dict.insert 3 "But Not Me" +## |> Dict.insert 3 "This has a different value" ## |> Dict.insert 4 "Or Me" ## -## expect Dict.keepShared first second == first +## expected = +## Dict.single 1 "Keep Me" +## |> Dict.insert 2 "And Me" +## +## expect Dict.keepShared first second == expected ## ``` -keepShared : Dict k v, Dict k v -> Dict k v where k implements Hash & Eq +keepShared : Dict k v, Dict k v -> Dict k v where k implements Hash & Eq, v implements Eq keepShared = \xs, ys -> if len ys < len xs then keepShared ys xs @@ -654,10 +657,11 @@ keepShared = \xs, ys -> xs (withCapacity (len xs)) (\state, k, v -> - if contains ys k then - insert state k v - else - state + when get ys k is + Ok yv if v == yv -> + insert state k v + _ -> + state ) ## Remove the key-value pairs in the first input that are also in the second diff --git a/crates/compiler/test_gen/src/gen_dict.rs b/crates/compiler/test_gen/src/gen_dict.rs index 6e0181223c..a82a803b96 100644 --- a/crates/compiler/test_gen/src/gen_dict.rs +++ b/crates/compiler/test_gen/src/gen_dict.rs @@ -436,7 +436,7 @@ fn keep_shared() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -fn keep_shared_prefer_first() { +fn keep_shared_value_must_match() { assert_evals_to!( indoc!( r#" @@ -453,14 +453,14 @@ fn keep_shared_prefer_first() { dict2 = Dict.empty {} |> Dict.insert 0 100 - |> Dict.insert 2 200 + |> Dict.insert 2 2 |> Dict.insert 4 300 Dict.keepShared dict1 dict2 |> Dict.values "# ), - RocList::from_slice(&[2, 4]), + RocList::from_slice(&[2]), RocList ); } diff --git a/crates/compiler/test_gen/src/gen_set.rs b/crates/compiler/test_gen/src/gen_set.rs index e046899e0f..75201c38a4 100644 --- a/crates/compiler/test_gen/src/gen_set.rs +++ b/crates/compiler/test_gen/src/gen_set.rs @@ -120,7 +120,7 @@ fn union() { |> Set.toList "# ), - RocList::from_slice(&[1, 2, 3, 4]), + RocList::from_slice(&[1, 3, 4, 2]), RocList ); }