@@ -401,6 +401,7 @@ import Utils.Containers.Internal.PtrEquality (ptrEq)
401401import Utils.Containers.Internal.StrictPair
402402import Utils.Containers.Internal.StrictMaybe
403403import Utils.Containers.Internal.BitQueue
404+ import Utils.Containers.Internal.EqOrdUtil (EqM (.. ), OrdM (.. ))
404405#ifdef DEFINE_ALTERF_FALLBACK
405406import Utils.Containers.Internal.BitUtil (wordSize )
406407#endif
@@ -4118,6 +4119,31 @@ deleteFindMax t = case maxViewWithKey t of
41184119 Nothing -> (error " Map.deleteFindMax: can not return the maximal element of an empty map" , Tip )
41194120 Just res -> res
41204121
4122+ {- -------------------------------------------------------------------
4123+ Iterator
4124+ --------------------------------------------------------------------}
4125+
4126+ -- See Note [Iterator] in Data.Set.Internal
4127+
4128+ iterDown :: Map k a -> Stack k a -> Stack k a
4129+ iterDown (Bin _ kx x l r) stk = iterDown l (Push kx x r stk)
4130+ iterDown Tip stk = stk
4131+
4132+ -- Create an iterator from a Map, starting at the smallest key.
4133+ iterator :: Map k a -> Stack k a
4134+ iterator m = iterDown m Nada
4135+
4136+ -- Get the next key-value and the remaining iterator.
4137+ iterNext :: Stack k a -> Maybe (StrictPair (KeyValue k a ) (Stack k a ))
4138+ iterNext (Push kx x r stk) = Just $! KeyValue kx x :*: iterDown r stk
4139+ iterNext Nada = Nothing
4140+ {-# INLINE iterNext #-}
4141+
4142+ -- Whether there are no more key-values in the iterator.
4143+ iterNull :: Stack k a -> Bool
4144+ iterNull (Push _ _ _ _) = False
4145+ iterNull Nada = True
4146+
41214147{- -------------------------------------------------------------------
41224148 [balance l x r] balances two trees with value x.
41234149 The sizes of the trees should balance after decreasing the
@@ -4284,41 +4310,69 @@ bin k x l r
42844310
42854311
42864312{- -------------------------------------------------------------------
4287- Eq converts the tree to a list. In a lazy setting, this
4288- actually seems one of the faster methods to compare two trees
4289- and it is certainly the simplest :-)
4313+ Eq
42904314--------------------------------------------------------------------}
4315+
42914316instance (Eq k ,Eq a ) => Eq (Map k a ) where
4292- t1 == t2 = (size t1 == size t2) && (toAscList t1 == toAscList t2)
4317+ m1 == m2 = liftEq2 (==) (==) m1 m2
4318+ {-# INLINABLE (==) #-}
42934319
4294- {- -------------------------------------------------------------------
4295- Ord
4296- --------------------------------------------------------------------}
4320+ -- | @since 0.5.9
4321+ instance Eq k => Eq1 (Map k ) where
4322+ liftEq = liftEq2 (==)
4323+ {-# INLINE liftEq #-}
42974324
4298- instance (Ord k , Ord v ) => Ord (Map k v ) where
4299- compare m1 m2 = compare (toAscList m1) (toAscList m2)
4325+ -- | @since 0.5.9
4326+ instance Eq2 Map where
4327+ liftEq2 keq eq m1 m2 = size m1 == size m2 && sameSizeLiftEq2 keq eq m1 m2
4328+ {-# INLINE liftEq2 #-}
4329+
4330+ -- Assumes the maps are of equal size to skip the final check
4331+ sameSizeLiftEq2
4332+ :: (ka -> kb -> Bool ) -> (a -> b -> Bool ) -> Map ka a -> Map kb b -> Bool
4333+ sameSizeLiftEq2 keq eq m1 m2 =
4334+ case runEqM (foldMapWithKey f m1) (iterator m2) of e :*: _ -> e
4335+ where
4336+ f kx x = EqM $ \ it -> case iterNext it of
4337+ Nothing -> False :*: it
4338+ Just (KeyValue ky y :*: it') -> (keq kx ky && eq x y) :*: it'
4339+ {-# INLINE sameSizeLiftEq2 #-}
43004340
43014341{- -------------------------------------------------------------------
4302- Lifted instances
4342+ Ord
43034343--------------------------------------------------------------------}
43044344
4305- -- | @since 0.5.9
4306- instance Eq2 Map where
4307- liftEq2 eqk eqv m n =
4308- size m == size n && liftEq (liftEq2 eqk eqv) (toList m) (toList n)
4345+ instance (Ord k , Ord v ) => Ord (Map k v ) where
4346+ compare m1 m2 = liftCmp2 compare compare m1 m2
4347+ {-# INLINABLE compare #-}
43094348
43104349-- | @since 0.5.9
4311- instance Eq k => Eq1 (Map k ) where
4312- liftEq = liftEq2 (==)
4350+ instance Ord k => Ord1 (Map k ) where
4351+ liftCompare = liftCmp2 compare
4352+ {-# INLINE liftCompare #-}
43134353
43144354-- | @since 0.5.9
43154355instance Ord2 Map where
4316- liftCompare2 cmpk cmpv m n =
4317- liftCompare (liftCompare2 cmpk cmpv) (toList m) (toList n)
4356+ liftCompare2 = liftCmp2
4357+ {-# INLINE liftCompare2 #-}
4358+
4359+ liftCmp2
4360+ :: (ka -> kb -> Ordering )
4361+ -> (a -> b -> Ordering )
4362+ -> Map ka a
4363+ -> Map kb b
4364+ -> Ordering
4365+ liftCmp2 kcmp cmp m1 m2 = case runOrdM (foldMapWithKey f m1) (iterator m2) of
4366+ o :*: it -> o <> if iterNull it then EQ else LT
4367+ where
4368+ f kx x = OrdM $ \ it -> case iterNext it of
4369+ Nothing -> GT :*: it
4370+ Just (KeyValue ky y :*: it') -> (kcmp kx ky <> cmp x y) :*: it'
4371+ {-# INLINE liftCmp2 #-}
43184372
4319- -- | @since 0.5.9
4320- instance Ord k => Ord1 ( Map k ) where
4321- liftCompare = liftCompare2 compare
4373+ {- -------------------------------------------------------------------
4374+ Lifted instances
4375+ ------------------------------------------------------------------- -}
43224376
43234377-- | @since 0.5.9
43244378instance Show2 Map where
0 commit comments