33{-# LANGUAGE PatternGuards #-}
44#if defined(__GLASGOW_HASKELL__)
55{-# LANGUAGE DeriveLift #-}
6+ {-# LANGUAGE MagicHash #-}
7+ {-# LANGUAGE UnboxedTuples #-}
68{-# LANGUAGE RoleAnnotations #-}
79{-# LANGUAGE StandaloneDeriving #-}
810{-# LANGUAGE Trustworthy #-}
911{-# LANGUAGE TypeFamilies #-}
1012#endif
1113#define USE_MAGIC_PROXY 1
1214
13- #ifdef USE_MAGIC_PROXY
14- {-# LANGUAGE MagicHash #-}
15- #endif
16-
1715{-# OPTIONS_HADDOCK not-home #-}
1816
1917#include "containers.h"
@@ -236,7 +234,9 @@ module Data.Map.Internal (
236234 -- * Traversal
237235 -- ** Map
238236 , map
237+ , map #
239238 , mapWithKey
239+ , mapWithKey #
240240 , traverseWithKey
241241 , traverseMaybeWithKey
242242 , mapAccum
@@ -301,6 +301,7 @@ module Data.Map.Internal (
301301
302302 , mapMaybe
303303 , mapMaybeWithKey
304+ , mapMaybeWithKey #
304305 , mapEither
305306 , mapEitherWithKey
306307
@@ -407,6 +408,7 @@ import Data.Data
407408import qualified Control.Category as Category
408409import Data.Coerce
409410#endif
411+ import Utils.Containers.Internal.UnboxedMaybe
410412
411413
412414{- -------------------------------------------------------------------
@@ -2849,6 +2851,7 @@ isProperSubmapOfBy f t1 t2
28492851filter :: (a -> Bool ) -> Map k a -> Map k a
28502852filter p m
28512853 = filterWithKey (\ _ x -> p x) m
2854+ {-# INLINE filter #-}
28522855
28532856-- | \(O(n)\). Filter all keys\/values that satisfy the predicate.
28542857--
@@ -2863,6 +2866,32 @@ filterWithKey p t@(Bin _ kx x l r)
28632866 | otherwise = link2 pl pr
28642867 where ! pl = filterWithKey p l
28652868 ! pr = filterWithKey p r
2869+ {-# NOINLINE [1] filterWithKey #-}
2870+
2871+ {-# RULES
2872+ "filterWK/filterWK" forall p q m. filterWithKey p (filterWithKey q m) =
2873+ filterWithKey (\k x -> q k x && p k x) m
2874+ "filterWK/map#" forall p f m. filterWithKey p (map# f m) =
2875+ mapMaybeWithKey# (\k x -> case f x of
2876+ (# y #)
2877+ | p k y -> Just# y
2878+ | otherwise -> Nothing#) m
2879+ "filterWK/mapWK#" forall p f m. filterWithKey p (mapWithKey# f m) =
2880+ mapMaybeWithKey# (\k x -> case f k x of
2881+ (# y #)
2882+ | p k y -> Just# y
2883+ | otherwise -> Nothing#) m
2884+ "map#/filterWK" forall f p m. map# f (filterWithKey p m) =
2885+ mapMaybeWithKey# (\k x ->
2886+ if p k x
2887+ then case f x of (# y #) -> Just# y
2888+ else Nothing#) m
2889+ "mapWK#/filterWK" forall f p m. mapWithKey# f (filterWithKey p m) =
2890+ mapMaybeWithKey# (\k x ->
2891+ if p k x
2892+ then case f k x of (# y #) -> Just# y
2893+ else Nothing#) m
2894+ #-}
28662895
28672896-- | \(O(n)\). Filter keys and values using an 'Applicative'
28682897-- predicate.
@@ -2977,17 +3006,60 @@ partitionWithKey p0 t0 = toPair $ go p0 t0
29773006
29783007mapMaybe :: (a -> Maybe b ) -> Map k a -> Map k b
29793008mapMaybe f = mapMaybeWithKey (\ _ x -> f x)
3009+ {-# INLINE mapMaybe #-}
29803010
29813011-- | \(O(n)\). Map keys\/values and collect the 'Just' results.
29823012--
29833013-- > let f k _ = if k < 5 then Just ("key : " ++ (show k)) else Nothing
29843014-- > mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
29853015
29863016mapMaybeWithKey :: (k -> a -> Maybe b ) -> Map k a -> Map k b
3017+ {-
29873018mapMaybeWithKey _ Tip = Tip
29883019mapMaybeWithKey f (Bin _ kx x l r) = case f kx x of
29893020 Just y -> link kx y (mapMaybeWithKey f l) (mapMaybeWithKey f r)
29903021 Nothing -> link2 (mapMaybeWithKey f l) (mapMaybeWithKey f r)
3022+ -}
3023+ mapMaybeWithKey f = \ m ->
3024+ mapMaybeWithKey# (\ k x -> toMaybe# (f k x)) m
3025+ {-# INLINE mapMaybeWithKey #-}
3026+
3027+ mapMaybeWithKey# :: (k -> a -> Maybe # b ) -> Map k a -> Map k b
3028+ mapMaybeWithKey# _ Tip = Tip
3029+ mapMaybeWithKey# f (Bin _ kx x l r) = case f kx x of
3030+ Just # y -> link kx y (mapMaybeWithKey# f l) (mapMaybeWithKey# f r)
3031+ Nothing # -> link2 (mapMaybeWithKey# f l) (mapMaybeWithKey# f r)
3032+ {-# NOINLINE [1] mapMaybeWithKey# #-}
3033+
3034+ {-# RULES
3035+ "mapMaybeWK#/map#" forall f g m. mapMaybeWithKey# f (map# g m) =
3036+ mapMaybeWithKey# (\k x -> case g x of (# y #) -> f k y) m
3037+ "map#/mapMaybeWK#" forall f g m. map# f (mapMaybeWithKey# g m) =
3038+ mapMaybeWithKey#
3039+ (\k x -> case g k x of
3040+ Nothing# -> Nothing#
3041+ Just# y -> case f y of (# z #) -> Just# z) m
3042+ "mapMaybeWK#/mapWK#" forall f g m. mapMaybeWithKey# f (mapWithKey# g m) =
3043+ mapMaybeWithKey# (\k x -> case g k x of (# y #) -> f k y) m
3044+ "mapWK#/mapMaybeWK#" forall f g m. mapWithKey# f (mapMaybeWithKey# g m) =
3045+ mapMaybeWithKey#
3046+ (\k x -> case g k x of
3047+ Nothing# -> Nothing#
3048+ Just# y -> case f k y of (# z #) -> Just# z) m
3049+ "mapMaybeWK#/mapMaybeWK#" forall f g m. mapMaybeWithKey# f (mapMaybeWithKey# g m) =
3050+ mapMaybeWithKey#
3051+ (\k x -> case g k x of
3052+ Nothing# -> Nothing#
3053+ Just# y -> f k y) m
3054+ "mapMaybeWK#/filterWK" forall f p m. mapMaybeWithKey# f (filterWithKey p m) =
3055+ mapMaybeWithKey# (\k x -> if p k x then f k x else Nothing#) m
3056+ "filterWK/mapMaybeWK#" forall p f m. filterWithKey p (mapMaybeWithKey# f m) =
3057+ mapMaybeWithKey# (\k x -> case f k x of
3058+ Nothing# -> Nothing#
3059+ Just# y
3060+ | p k y -> Just# y
3061+ | otherwise -> Nothing#) m
3062+ #-}
29913063
29923064-- | \(O(n)\). Traverse keys\/values and collect the 'Just' results.
29933065--
@@ -3045,18 +3117,34 @@ mapEitherWithKey f0 t0 = toPair $ go f0 t0
30453117-- > map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
30463118
30473119map :: (a -> b ) -> Map k a -> Map k b
3120+ #ifdef __GLASGOW_HASKELL__
3121+ -- We define map using map# solely to reduce the number of rewrite
3122+ -- rules we need.
3123+ map f = map # (\ x -> (# f x # ))
3124+ {-# INLINABLE map #-}
3125+ #else
30483126map f = go where
30493127 go Tip = Tip
30503128 go (Bin sx kx x l r) = Bin sx kx (f x) (go l) (go r)
3051- -- We use a `go` function to allow `map` to inline. This makes
3052- -- a big difference if someone uses `map (const x) m` instead
3053- -- of `x <$ m`; it doesn't seem to do any harm.
3129+ #endif
30543130
30553131#ifdef __GLASGOW_HASKELL__
3056- {-# NOINLINE [1] map #-}
3132+ map # :: (a -> (# b # )) -> Map k a -> Map k b
3133+ map # f = go where
3134+ go Tip = Tip
3135+ go (Bin sx kx x l r)
3136+ | (# y # ) <- f x
3137+ = Bin sx kx y (go l) (go r)
3138+ -- We use a `go` function to allow `map#` to inline. Without this,
3139+ -- we'd slow down both strict and lazy map, which wouldn't be great.
3140+ -- This also lets us avoid a custom implementation of <$
3141+
3142+ {-# NOINLINE [1] map# #-}
3143+ -- Perhaps surprisingly, this map#/coerce rule seems to work. Hopefully,
3144+ -- it will continue to do so.
30573145{-# RULES
3058- "map/map" forall f g xs . map f (map g xs) = map (f . g ) xs
3059- "map/coerce" map coerce = coerce
3146+ "map# /map# " forall f g xs . map# f (map# g xs) = map# (\x -> case g x of (# y #) -> f y ) xs
3147+ "map# /coerce" map# (\x -> (# coerce x #)) = coerce
30603148 #-}
30613149#endif
30623150
@@ -3066,21 +3154,33 @@ map f = go where
30663154-- > mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
30673155
30683156mapWithKey :: (k -> a -> b ) -> Map k a -> Map k b
3157+ #ifdef __GLASGOW_HASKELL__
3158+ mapWithKey f = mapWithKey# (\ k a -> (# f k a # ))
3159+ {-# INLINABLE mapWithKey #-}
3160+ #else
30693161mapWithKey _ Tip = Tip
30703162mapWithKey f (Bin sx kx x l r) = Bin sx kx (f kx x) (mapWithKey f l) (mapWithKey f r)
3163+ #endif
3164+
3165+ -- | A version of 'mapWithKey' that takes a function producing a unary
3166+ -- unboxed tuple.
3167+ mapWithKey# :: (k -> a -> (# b # )) -> Map k a -> Map k b
3168+ mapWithKey# f = go where
3169+ go Tip = Tip
3170+ go (Bin sx kx x l r)
3171+ | (# y # ) <- f kx x
3172+ = Bin sx kx y (go l) (go r)
30713173
30723174#ifdef __GLASGOW_HASKELL__
3073- {-# NOINLINE [1] mapWithKey #-}
3175+ {-# NOINLINE [1] mapWithKey# #-}
30743176{-# RULES
3075- "mapWithKey/mapWithKey" forall f g xs . mapWithKey f (mapWithKey g xs) =
3076- mapWithKey (\k a -> f k (g k a)) xs
3077- "mapWithKey/map" forall f g xs . mapWithKey f (map g xs) =
3078- mapWithKey (\k a -> f k (g a)) xs
3079- "map/mapWithKey" forall f g xs . map f (mapWithKey g xs) =
3080- mapWithKey (\k a -> f (g k a)) xs
3177+ "mapWK#/mapWK#" forall f g xs. mapWithKey# f (mapWithKey# g xs) = mapWithKey# (\k x -> case g k x of (# y #) -> f k y) xs
3178+ "mapWK#/map#" forall f g xs. mapWithKey# f (map# g xs) = mapWithKey# (\k x -> case g x of (# y #) -> f k y) xs
3179+ "map#/mapWK#" forall f g xs. map# f (mapWithKey# g xs) = mapWithKey# (\k x -> case g k x of (# y #) -> f y) xs
30813180 #-}
30823181#endif
30833182
3183+
30843184-- | \(O(n)\).
30853185-- @'traverseWithKey' f m == 'fromList' <$> 'traverse' (\(k, v) -> (,) k <$> f k v) ('toList' m)@
30863186-- That is, behaves exactly like a regular 'traverse' except that the traversing
@@ -4195,10 +4295,12 @@ instance (Ord k, Read k) => Read1 (Map k) where
41954295--------------------------------------------------------------------}
41964296instance Functor (Map k ) where
41974297 fmap f m = map f m
4198- #ifdef __GLASGOW_HASKELL__
4199- _ <$ Tip = Tip
4200- a <$ (Bin sx kx _ l r) = Bin sx kx a (a <$ l) (a <$ r)
4201- #endif
4298+ {-# INLINABLE fmap #-}
4299+ a <$ m = map (const a) m
4300+ -- For some reason, we need an explicit INLINE or INLINABLE pragma to
4301+ -- get the unfolding to use map rather than expanding into a recursive
4302+ -- function that RULES will never match. Hmm....
4303+ {-# INLINABLE (<$) #-}
42024304
42034305-- | Traverses in order of increasing key.
42044306instance Traversable (Map k ) where
0 commit comments