git.iko.soy/typeable/refined-containers
on main help sign in
Fix zipWith strictness
commitcd80f22843e5d3a688ed46b29584844310869aa9 authormniip <mniip@mniip.com> dateMon 24 Mar 2025, 16:23 (2 years ago) parentd85e2a4
3 files changed+52−3
src/Data/HashMap/Strict/Refined.hs+9−1 src/Data/IntMap/Strict/Refined.hs+23−1 src/Data/Map/Strict/Refined.hs+20−1
src/Data/HashMap/Strict/Refined.hs+9−1
@@ -137,7 +137,7 @@ import Data.Functor
137137import qualified Data.HashMap.Strict as HashMap
138138import Data.HashMap.Common.Refined
139139 ( HashMap(..), Key, unsafeCastKey, unsafeKey, SomeHashMapWith(..)
140− , Some2HashMapWith(..), (!), zipWith
140+ , Some2HashMapWith(..), (!)
141141 )
142142import qualified Data.HashMap.Common.Refined as Common
143143import qualified Data.HashSet as HashSet
@@ -353,6 +353,14 @@ updateLookupWithKey f k (HashMap m) =
353353
354354-- | Given two maps proven to have the same keys, for each key apply the
355355-- function to the associated values, to obtain a new map with the same keys.
356+zipWith
357+ :: forall s k a b c. Hashable k
358+ => (a -> b -> c) -> HashMap s k a -> HashMap s k b -> HashMap s k c
359+zipWith f (HashMap m1) (HashMap m2) = HashMap $ HashMap.intersectionWith f m1 m2
360+
361+-- | Given two maps proven to have the same keys, for each key apply the
362+-- function to the associated values and the key, to obtain a new map with the
363+-- same keys.
356364zipWithKey
357365 :: forall s k a b c. Hashable k
358366 => (Key s k -> a -> b -> c) -> HashMap s k a -> HashMap s k b -> HashMap s k c
src/Data/IntMap/Strict/Refined.hs+23−1
@@ -145,7 +145,7 @@ import Data.Functor
145145import qualified Data.IntMap.Strict as IntMap
146146import Data.IntMap.Common.Refined
147147 ( IntMap(..), Key, unsafeCastKey, unsafeKey, SomeIntMapWith(..)
148− , Some2IntMapWith(..), (!), zipWith
148+ , Some2IntMapWith(..), (!)
149149 )
150150import qualified Data.IntMap.Common.Refined as Common
151151import Data.Proxy
@@ -344,6 +344,28 @@ updateLookupWithKey f k (IntMap m)
344344
345345-- | Given two maps proven to have the same keys, for each key apply the
346346-- function to the associated values, to obtain a new map with the same keys.
347+zipWith
348+ :: forall s a b c. (a -> b -> c)
349+ -> IntMap s a
350+ -> IntMap s b
351+ -> IntMap s c
352+zipWith f (IntMap m1) (IntMap m2) = IntMap
353+ $ IntMap.mergeWithKey (\_ x y -> Just $ f x y)
354+ (\m -> if IntMap.null m
355+ then IntMap.empty
356+ else
357+ error "zipWith: bug: Data.IntMap.Strict.Refined has been subverted")
358+ (\m -> if IntMap.null m
359+ then IntMap.empty
360+ else
361+ error "zipWith: bug: Data.IntMap.Strict.Refined has been subverted")
362+ -- ^ Work around https://github.com/haskell/containers/issues/979
363+ m1
364+ m2
365+
366+-- | Given two maps proven to have the same keys, for each key apply the
367+-- function to the associated values and the key, to obtain a new map with the
368+-- same keys.
347369zipWithKey
348370 :: forall s a b c. (Key s -> a -> b -> c)
349371 -> IntMap s a
src/Data/Map/Strict/Refined.hs+20−1
@@ -78,6 +78,7 @@ module Data.Map.Strict.Refined
7878 , Common.disjoint
7979 , DisjointProof(..)
8080 -- * Combine
81+ , zipWith
8182 , zipWithKey
8283 , bind
8384 , Common.union
@@ -160,7 +161,7 @@ import Data.Proxy
160161import Data.Reflection
161162import Data.Traversable
162163import Data.Type.Coercion
163−import Prelude hiding (lookup, map, null)
164+import Prelude hiding (lookup, map, null, zipWith)
164165import Refined
165166import Refined.Unsafe
166167
@@ -355,6 +356,24 @@ updateLookupWithKey f k (Map m)
355356
356357-- | Given two maps proven to have the same keys, for each key apply the
357358-- function to the associated values, to obtain a new map with the same keys.
359+zipWith
360+ :: forall s k a b c. Ord k
361+ => (a -> b -> c) -> Map s k a -> Map s k b -> Map s k c
362+zipWith f (Map m1) (Map m2) = Map
363+ $ Map.mergeWithKey (\_ x y -> Just $ f x y)
364+ (\m -> if Map.null m
365+ then Map.empty
366+ else error "zipWith: bug: Data.Map.Strict.Refined has been subverted")
367+ (\m -> if Map.null m
368+ then Map.empty
369+ else error "zipWith: bug: Data.Map.Strict.Refined has been subverted")
370+ -- ^ Work around https://github.com/haskell/containers/issues/979
371+ m1
372+ m2
373+
374+-- | Given two maps proven to have the same keys, for each key apply the
375+-- function to the associated values and the key, to obtain a new map with the
376+-- same keys.
358377zipWithKey
359378 :: forall s k a b c. Ord k
360379 => (Key s k -> a -> b -> c) -> Map s k a -> Map s k b -> Map s k c