77{-# LANGUAGE MagicHash #-}
88{-# LANGUAGE UnboxedSums #-}
99{-# LANGUAGE UnboxedTuples #-}
10+ {-# LANGUAGE PatternSynonyms #-}
11+ {-# LANGUAGE TypeInType #-}
12+ {-# LANGUAGE ScopedTypeVariables #-}
1013#endif
1114
1215#include "containers.h"
@@ -221,7 +224,7 @@ module Data.IntMap.Strict (
221224 , showTreeWith
222225 ) where
223226
224- import Prelude hiding (lookup ,map ,filter ,foldr ,foldl ,null )
227+ import Prelude hiding (lookup ,map ,filter ,foldr ,foldl ,null , ($!) )
225228
226229import Data.Bits
227230import qualified Data.IntMap.Internal as L
@@ -310,6 +313,8 @@ import qualified Data.IntSet.Internal as IntSet
310313import Utils.Containers.Internal.BitUtil
311314#if __GLASGOW_HASKELL__ >= 802
312315import Utils.Containers.Internal.PtrEquality (ptrEq )
316+ import Utils.Containers.Internal.UnboxedMaybe (Maybe #, pattern Nothing #, pattern Just #, toMaybe )
317+ import GHC.Exts (TYPE )
313318#endif
314319import Utils.Containers.Internal.StrictFold
315320import Utils.Containers.Internal.StrictPair
@@ -336,6 +341,19 @@ import Control.Applicative (Applicative (..), liftA2)
336341-- > map (\ v -> undefined) m == undefined -- m is not empty
337342-- > mapKeys (\ k -> undefined) m == undefined -- m is not empty
338343
344+ #if __GLASGOW_HASKELL__ >= 802
345+ -- Annoyingly, Prelude.$! is not (yet) polykinded. So we just define
346+ -- our own.
347+ infixr 0 $!
348+ ($!) :: forall r a (b :: TYPE r ).
349+ (a -> b ) -> a -> b
350+ f $! (! x) = f x
351+ #endif
352+ #else
353+ ($!) :: (a -> b ) -> a -> b
354+ f $! (! x) = f x
355+ #endif
356+
339357{- -------------------------------------------------------------------
340358 Query
341359--------------------------------------------------------------------}
@@ -569,9 +587,11 @@ updateLookupWithKey f0 !k0 t0 = toPair $ go f0 k0 t0
569587-- In short : @'lookup' k ('alter' f k m) = f ('lookup' k m)@.
570588#if __GLASGOW_HASKELL__ >= 802
571589alter :: (Maybe a -> Maybe a ) -> Key -> IntMap a -> IntMap a
572- alter f ! k t = case alter# f k t of
573- (# (# # ) | # ) -> t
574- (# | t' # ) -> t'
590+ alter f ! k t = case alter# (\ m -> case f (toMaybe m) of
591+ Nothing -> Nothing #
592+ Just x -> Just # x) k t of
593+ Nothing # -> t
594+ Just # t' -> t'
575595{-# INLINE alter #-}
576596
577597
@@ -580,31 +600,31 @@ alter f !k t = case alter# f k t of
580600--
581601-- If no modifications are made to the map (# (# #) | #) is returned, otherwise
582602-- (# | newMap #) is returned.
583- alter# :: (Maybe a -> Maybe a ) -> Key -> IntMap a -> ( # (# # ) | IntMap a # )
603+ alter# :: (Maybe # a -> Maybe # a ) -> Key -> IntMap a -> Maybe # (IntMap a )
584604alter# f ! k t@ (Bin p m l r)
585- | nomatch k p m = case f Nothing of
586- Nothing -> ( # ( # # ) | # )
587- Just ! x -> ( # | link k (Tip k x) p t # )
605+ | nomatch k p m = case f Nothing # of
606+ Nothing # -> Nothing #
607+ Just # ! x -> Just # $! link k (Tip k x) p t
588608 | zero k m = case alter# f k l of
589- ( # ( # # ) | # ) -> ( # ( # # ) | # )
590- ( # | l' # ) -> ( # | binCheckLeft p m l' r # )
609+ Nothing # -> Nothing #
610+ Just # l' -> Just # $! binCheckLeft p m l' r
591611
592612 | otherwise = case alter# f k r of
593- ( # ( # # ) | # ) -> ( # ( # # ) | # )
594- ( # | r' # ) -> ( # | binCheckRight p m l r' # )
613+ Nothing # -> Nothing #
614+ Just # r' -> Just # $! binCheckRight p m l r'
595615
596616alter# f k t@ (Tip ky y)
597- | k== ky = case f (Just y) of
598- Just x -> if x `ptrEq` y
599- then ( # ( # # ) | # )
600- else ( # | Tip ky x # )
601- Nothing -> ( # | Nil # )
602- | otherwise = case f Nothing of
603- Just ! x -> ( # | link k (Tip k x) ky t # )
604- Nothing -> ( # ( # # ) | # )
605- alter# f k Nil = case f Nothing of
606- Just ! x -> ( # | Tip k x # )
607- Nothing -> ( # ( # # ) | # )
617+ | k== ky = case f (Just # y) of
618+ Just # ! x -> if x `ptrEq` y
619+ then Nothing #
620+ else Just # ( Tip ky x)
621+ Nothing # -> Just # Nil
622+ | otherwise = case f Nothing # of
623+ Just # ! x -> Just # $! link k (Tip k x) ky t
624+ Nothing # -> Nothing #
625+ alter# f k Nil = case f Nothing # of
626+ Just # ! x -> Just # ( Tip k x)
627+ Nothing # -> Nothing #
608628
609629#else
610630alter :: (Maybe a -> Maybe a ) -> Key -> IntMap a -> IntMap a
0 commit comments