From 778689dcf679cdb00fcd1ad0ee1f4492d7e8a164 Mon Sep 17 00:00:00 2001 From: ocramz Date: Tue, 15 Jan 2019 12:20:56 +0100 Subject: [PATCH 1/3] add Array.foldlM' and foldlWithKeyM' --- Data/HashMap/Array.hs | 13 +++++++++++++ Data/HashMap/Base.hs | 12 ++++++++++++ Data/HashMap/Lazy.hs | 1 + Data/HashMap/Strict.hs | 1 + Data/HashMap/Strict/Base.hs | 1 + 5 files changed, 28 insertions(+) diff --git a/Data/HashMap/Array.hs b/Data/HashMap/Array.hs index 0149da4d..f60ae15d 100644 --- a/Data/HashMap/Array.hs +++ b/Data/HashMap/Array.hs @@ -43,6 +43,7 @@ module Data.HashMap.Array -- * Folds , foldl' , foldr + , foldlM' , thaw , map @@ -418,6 +419,18 @@ foldl' f = \ z0 ary0 -> go ary0 (length ary0) 0 z0 (# x #) -> go ary n (i+1) (f z x) {-# INLINE foldl' #-} +foldlM' :: Monad m => (b -> a -> m b) -> b -> Array a -> m b +foldlM' f = \ z0 ary0 -> go ary0 (length ary0) 0 z0 + where + go ary n i !z + | i >= n = pure z + | otherwise + = case index# ary i of + (# x #) -> do + fzx <- f z x + go ary n (i+1) fzx +{-# INLINE foldlM' #-} + foldr :: (a -> b -> b) -> b -> Array a -> b foldr f = \ z0 ary0 -> go ary0 (length ary0) 0 z0 where diff --git a/Data/HashMap/Base.hs b/Data/HashMap/Base.hs index 553d2b3a..019c84e8 100644 --- a/Data/HashMap/Base.hs +++ b/Data/HashMap/Base.hs @@ -58,6 +58,7 @@ module Data.HashMap.Base -- * Folds , foldl' , foldlWithKey' + , foldlWithKeyM' , foldr , foldrWithKey @@ -1551,6 +1552,17 @@ foldlWithKey' f = go go z (Collision _ ary) = A.foldl' (\ z' (L k v) -> f z' k v) z ary {-# INLINE foldlWithKey' #-} +-- | /O(n)/ Monadic version of 'foldlWithKey''. +foldlWithKeyM' :: Monad m => (a -> k -> v -> m a) -> a -> HashMap k v -> m a +foldlWithKeyM' f = go + where + go !z Empty = pure z + go z (Leaf _ (L k v)) = f z k v + go z (BitmapIndexed _ ary) = A.foldlM' go z ary + go z (Full ary) = A.foldlM' go z ary + go z (Collision _ ary) = A.foldlM' (\ z' (L k v) -> f z' k v) z ary +{-# INLINE foldlWithKeyM' #-} + -- | /O(n)/ Reduce this map by applying a binary operator to all -- elements, using the given starting value (typically the -- right-identity of the operator). diff --git a/Data/HashMap/Lazy.hs b/Data/HashMap/Lazy.hs index c7306350..7362c8a8 100644 --- a/Data/HashMap/Lazy.hs +++ b/Data/HashMap/Lazy.hs @@ -70,6 +70,7 @@ module Data.HashMap.Lazy -- * Folds , foldl' , foldlWithKey' + , foldlWithKeyM' , foldr , foldrWithKey diff --git a/Data/HashMap/Strict.hs b/Data/HashMap/Strict.hs index 3af68b7f..1bf87929 100644 --- a/Data/HashMap/Strict.hs +++ b/Data/HashMap/Strict.hs @@ -69,6 +69,7 @@ module Data.HashMap.Strict -- * Folds , foldl' , foldlWithKey' + , foldlWithKeyM' , foldr , foldrWithKey diff --git a/Data/HashMap/Strict/Base.hs b/Data/HashMap/Strict/Base.hs index 890d18ff..cc8122e6 100644 --- a/Data/HashMap/Strict/Base.hs +++ b/Data/HashMap/Strict/Base.hs @@ -71,6 +71,7 @@ module Data.HashMap.Strict.Base -- * Folds , foldl' , foldlWithKey' + , foldlWithKeyM' , HM.foldr , foldrWithKey From 039a443b4e794174967fdccf1cc9a65e7b83484e Mon Sep 17 00:00:00 2001 From: ocramz Date: Tue, 15 Jan 2019 12:42:11 +0100 Subject: [PATCH 2/3] fix for backwards compat --- Data/HashMap/Array.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Data/HashMap/Array.hs b/Data/HashMap/Array.hs index f60ae15d..ccdcf9dd 100644 --- a/Data/HashMap/Array.hs +++ b/Data/HashMap/Array.hs @@ -423,7 +423,7 @@ foldlM' :: Monad m => (b -> a -> m b) -> b -> Array a -> m b foldlM' f = \ z0 ary0 -> go ary0 (length ary0) 0 z0 where go ary n i !z - | i >= n = pure z + | i >= n = return z | otherwise = case index# ary i of (# x #) -> do From 9febf1b35ac4d01479c2922f9db63f88d41c3f12 Mon Sep 17 00:00:00 2001 From: ocramz Date: Tue, 15 Jan 2019 12:49:54 +0100 Subject: [PATCH 3/3] fix for backwards compat --- Data/HashMap/Base.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Data/HashMap/Base.hs b/Data/HashMap/Base.hs index 019c84e8..d6b28f54 100644 --- a/Data/HashMap/Base.hs +++ b/Data/HashMap/Base.hs @@ -1556,7 +1556,7 @@ foldlWithKey' f = go foldlWithKeyM' :: Monad m => (a -> k -> v -> m a) -> a -> HashMap k v -> m a foldlWithKeyM' f = go where - go !z Empty = pure z + go !z Empty = return z go z (Leaf _ (L k v)) = f z k v go z (BitmapIndexed _ ary) = A.foldlM' go z ary go z (Full ary) = A.foldlM' go z ary