From ce5b645b49e7df23ed88e435b47d40ba10054f40 Mon Sep 17 00:00:00 2001 From: flycloudc Date: Thu, 3 Jul 2025 10:55:14 +0800 Subject: [PATCH] fix(immut/hashmap): prioritize right values --- immut/hashmap/HAMT.mbt | 24 +++++------------------- immut/hashmap/HAMT_test.mbt | 6 +++--- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/immut/hashmap/HAMT.mbt b/immut/hashmap/HAMT.mbt index 7d1fa5dd3..07206ce49 100644 --- a/immut/hashmap/HAMT.mbt +++ b/immut/hashmap/HAMT.mbt @@ -319,23 +319,9 @@ pub fn[K, V] size(self : T[K, V]) -> Int { } ///| -/// Union two hashmaps +/// Union two hashmaps, right-hand side element is prioritized pub fn[K : Eq + Hash, V] T::union(self : T[K, V], other : T[K, V]) -> T[K, V] { - match (self, other) { - (_, Empty) => self - (Empty, _) => other - (_, Leaf(k, v)) => self.add(k, v) - (Leaf(k, v), _) => - // right-hand side element is prioritized - // like Clojure's merge - match other.get(k) { - Some(_) => other - None => other.add(k, v) - } - (Branch(sa1), Branch(sa2)) => - Branch(sa1.union(sa2, (m1, m2) => m1.union(m2))) - (_, _) => self.iter().fold(init=other, (m, kv) => m.add(kv.0, kv.1)) - } + other.iter().fold(init=self, (m, kv) => m.add(kv.0, kv.1)) } ///| @@ -371,15 +357,15 @@ pub fn[K : Eq + Hash, V] T::union_with( } ///| -/// Intersect two hashmaps +/// Intersect two hashmaps, right-hand side element is prioritized pub fn[K : Eq + Hash, V] T::intersection( self : T[K, V], other : T[K, V] ) -> T[K, V] { self .iter() - .fold(init=Empty, (m, kv) => if other.get(kv.0) is Some(_) { - m.add(kv.0, kv.1) + .fold(init=Empty, (m, kv) => if other.get(kv.0) is Some(v2) { + m.add(kv.0, v2) } else { m }) diff --git a/immut/hashmap/HAMT_test.mbt b/immut/hashmap/HAMT_test.mbt index ce0773473..d4af2da6d 100644 --- a/immut/hashmap/HAMT_test.mbt +++ b/immut/hashmap/HAMT_test.mbt @@ -548,7 +548,7 @@ test "HAMT::union with collision" { let m2 = @hashmap.of([(MyString("b"), 20), (MyString("c"), 3)]) let u = m1.union(m2) assert_eq(u.get(MyString("a")), Some(1)) - assert_eq(u.get(MyString("b")), Some(2)) + assert_eq(u.get(MyString("b")), Some(20)) assert_eq(u.get(MyString("c")), Some(3)) } @@ -566,7 +566,7 @@ test "HAMT::union all cases" { let collision2 = @hashmap.of([(MyString("b"), 20), (MyString("c"), 3)]) let u2 = collision.union(collision2) assert_eq(u2.get(MyString("a")), Some(1)) - assert_eq(u2.get(MyString("b")), Some(2)) + assert_eq(u2.get(MyString("b")), Some(20)) assert_eq(u2.get(MyString("c")), Some(3)) } @@ -605,7 +605,7 @@ test "HAMT::intersection with branch" { let inter = m1.intersection(m2) assert_eq(inter.get(1), None) assert_eq(inter.get(2), Some(2)) - assert_eq(inter.get(3), Some(3)) + assert_eq(inter.get(3), Some(30)) assert_eq(inter.get(4), None) }