1
1
{-# LANGUAGE CPP #-}
2
2
{-# LANGUAGE BangPatterns #-}
3
+ {-# LANGUAGE PatternGuards #-}
3
4
#if __GLASGOW_HASKELL__
4
5
{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
5
6
#endif
@@ -131,7 +132,7 @@ module Data.Map.Internal (
131
132
Map (.. ) -- instance Eq,Show,Read
132
133
133
134
-- * Operators
134
- , (!) , (\\)
135
+ , (!) , (!?) , ( \\)
135
136
136
137
-- * Query
137
138
, null
@@ -312,6 +313,8 @@ module Data.Map.Internal (
312
313
, splitAt
313
314
314
315
-- * Min\/Max
316
+ , lookupMin
317
+ , lookupMax
315
318
, findMin
316
319
, findMax
317
320
, deleteMin
@@ -406,7 +409,7 @@ import Data.Coerce
406
409
{- -------------------------------------------------------------------
407
410
Operators
408
411
--------------------------------------------------------------------}
409
- infixl 9 ! ,\\ --
412
+ infixl 9 ! ,!? , \\ --
410
413
411
414
-- | /O(log n)/. Find the value at a key.
412
415
-- Calls 'error' when the element can not be found.
@@ -417,14 +420,26 @@ infixl 9 !,\\ --
417
420
(!) :: Ord k => Map k a -> k -> a
418
421
(!) m k = find k m
419
422
#if __GLASGOW_HASKELL__
420
- {-# INLINABLE (!) #-}
423
+ {-# INLINE (!) #-}
424
+ #endif
425
+
426
+ -- | /O(log n)/. Find the value at a key.
427
+ -- Returns 'Nothing' when the element can not be found.
428
+ --
429
+ -- prop> fromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
430
+ -- prop> fromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
431
+
432
+ (!?) :: Ord k => Map k a -> k -> Maybe a
433
+ (!?) m k = lookup k m
434
+ #if __GLASGOW_HASKELL__
435
+ {-# INLINE (!?) #-}
421
436
#endif
422
437
423
438
-- | Same as 'difference'.
424
439
(\\) :: Ord k => Map k a -> Map k b -> Map k a
425
440
m1 \\ m2 = difference m1 m2
426
441
#if __GLASGOW_HASKELL__
427
- {-# INLINABLE (\\) #-}
442
+ {-# INLINE (\\) #-}
428
443
#endif
429
444
430
445
{- -------------------------------------------------------------------
@@ -1554,25 +1569,56 @@ deleteAt !i t =
1554
1569
{- -------------------------------------------------------------------
1555
1570
Minimal, Maximal
1556
1571
--------------------------------------------------------------------}
1572
+
1573
+ lookupMinSure :: k -> a -> Map k a -> (k , a )
1574
+ lookupMinSure k a Tip = (k, a)
1575
+ lookupMinSure _ _ (Bin _ k a l _) = lookupMinSure k a l
1576
+
1577
+ -- | /O(log n)/. The minimal key of the map. Returns 'Nothing' if the map is empty.
1578
+ --
1579
+ -- > lookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
1580
+ -- > findMin empty = Nothing
1581
+ --
1582
+ -- @since 0.5.9
1583
+
1584
+ lookupMin :: Map k a -> Maybe (k ,a )
1585
+ lookupMin Tip = Nothing
1586
+ lookupMin (Bin _ k x l _) = Just $! lookupMinSure k x l
1587
+
1557
1588
-- | /O(log n)/. The minimal key of the map. Calls 'error' if the map is empty.
1558
1589
--
1559
1590
-- > findMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
1560
1591
-- > findMin empty Error: empty map has no minimal element
1561
1592
1562
1593
findMin :: Map k a -> (k ,a )
1563
- findMin ( Bin _ kx x Tip _) = (kx,x)
1564
- findMin ( Bin _ _ _ l _) = findMin l
1565
- findMin Tip = error " Map.findMin: empty map has no minimal element"
1594
+ findMin t
1595
+ | Just r <- lookupMin t = r
1596
+ | otherwise = error " Map.findMin: empty map has no minimal element"
1566
1597
1567
1598
-- | /O(log n)/. The maximal key of the map. Calls 'error' if the map is empty.
1568
1599
--
1569
1600
-- > findMax (fromList [(5,"a"), (3,"b")]) == (5,"a")
1570
1601
-- > findMax empty Error: empty map has no maximal element
1571
1602
1603
+ lookupMaxSure :: k -> a -> Map k a -> (k , a )
1604
+ lookupMaxSure k a Tip = (k, a)
1605
+ lookupMaxSure _ _ (Bin _ k a _ r) = lookupMaxSure k a r
1606
+
1607
+ -- | /O(log n)/. The maximal key of the map. Returns 'Nothing' if the map is empty.
1608
+ --
1609
+ -- > lookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
1610
+ -- > lookupMax empty = Nothing
1611
+ --
1612
+ -- @since 0.5.9
1613
+
1614
+ lookupMax :: Map k a -> Maybe (k , a )
1615
+ lookupMax Tip = Nothing
1616
+ lookupMax (Bin _ k x _ r) = Just $! lookupMaxSure k x r
1617
+
1572
1618
findMax :: Map k a -> (k ,a )
1573
- findMax ( Bin _ kx x _ Tip ) = (kx,x)
1574
- findMax ( Bin _ _ _ _ r) = findMax r
1575
- findMax Tip = error " Map.findMax: empty map has no maximal element"
1619
+ findMax t
1620
+ | Just r <- lookupMax t = r
1621
+ | otherwise = error " Map.findMax: empty map has no maximal element"
1576
1622
1577
1623
-- | /O(log n)/. Delete the minimal key. Returns an empty map if the map is empty.
1578
1624
--
@@ -1645,7 +1691,9 @@ updateMaxWithKey f (Bin _ kx x l r) = balanceL kx x l (updateMaxWithKey f r)
1645
1691
1646
1692
minViewWithKey :: Map k a -> Maybe ((k ,a ), Map k a )
1647
1693
minViewWithKey Tip = Nothing
1648
- minViewWithKey x = Just $! deleteFindMin x
1694
+ minViewWithKey (Bin _ k x l r) =
1695
+ case minViewSure k x l r of
1696
+ MinView km xm t -> Just ((km, xm), t)
1649
1697
1650
1698
-- | /O(log n)/. Retrieves the maximal (key,value) pair of the map, and
1651
1699
-- the map stripped of that element, or 'Nothing' if passed an empty map.
@@ -1655,7 +1703,9 @@ minViewWithKey x = Just $! deleteFindMin x
1655
1703
1656
1704
maxViewWithKey :: Map k a -> Maybe ((k ,a ), Map k a )
1657
1705
maxViewWithKey Tip = Nothing
1658
- maxViewWithKey x = Just $! deleteFindMax x
1706
+ maxViewWithKey (Bin _ k x l r) =
1707
+ case maxViewSure k x l r of
1708
+ MaxView km xm t -> Just ((km, xm), t)
1659
1709
1660
1710
-- | /O(log n)/. Retrieves the value associated with minimal key of the
1661
1711
-- map, and the map stripped of that element, or 'Nothing' if passed an
@@ -1665,8 +1715,9 @@ maxViewWithKey x = Just $! deleteFindMax x
1665
1715
-- > minView empty == Nothing
1666
1716
1667
1717
minView :: Map k a -> Maybe (a , Map k a )
1668
- minView Tip = Nothing
1669
- minView x = Just $! (first snd $ deleteFindMin x)
1718
+ minView t = case minViewWithKey t of
1719
+ Nothing -> Nothing
1720
+ Just ((_, x), t') -> Just (x, t')
1670
1721
1671
1722
-- | /O(log n)/. Retrieves the value associated with maximal key of the
1672
1723
-- map, and the map stripped of that element, or 'Nothing' if passed an
@@ -1676,13 +1727,9 @@ minView x = Just $! (first snd $ deleteFindMin x)
1676
1727
-- > maxView empty == Nothing
1677
1728
1678
1729
maxView :: Map k a -> Maybe (a , Map k a )
1679
- maxView Tip = Nothing
1680
- maxView x = Just $! (first snd $ deleteFindMax x)
1681
-
1682
- -- Update the 1st component of a tuple (stricter version of
1683
- -- Control.Arrow.first)
1684
- first :: (a -> b ) -> (a ,c ) -> (b ,c )
1685
- first f (x,y) = (f x, y)
1730
+ maxView t = case maxViewWithKey t of
1731
+ Nothing -> Nothing
1732
+ Just ((_, x), t') -> Just (x, t')
1686
1733
1687
1734
{- -------------------------------------------------------------------
1688
1735
Union.
@@ -3670,39 +3717,48 @@ link2 l@(Bin sizeL kx x lx rx) r@(Bin sizeR ky y ly ry)
3670
3717
glue :: Map k a -> Map k a -> Map k a
3671
3718
glue Tip r = r
3672
3719
glue l Tip = l
3673
- glue l r
3674
- | size l > size r = let ((km,m),l') = deleteFindMax l in balanceR km m l' r
3675
- | otherwise = let ((km,m),r') = deleteFindMin r in balanceL km m l r'
3720
+ glue l@ (Bin sl kl xl ll lr) r@ (Bin sr kr xr rl rr)
3721
+ | sl > sr = let ! (MaxView km m l') = maxViewSure kl xl ll lr in balanceR km m l' r
3722
+ | otherwise = let ! (MinView km m r') = minViewSure kr xr rl rr in balanceL km m l r'
3723
+
3724
+ data MinView k a = MinView ! k a ! (Map k a )
3725
+ data MaxView k a = MaxView ! k a ! (Map k a )
3676
3726
3727
+ minViewSure :: k -> a -> Map k a -> Map k a -> MinView k a
3728
+ minViewSure = go
3729
+ where
3730
+ go k x Tip r = MinView k x r
3731
+ go k x (Bin _ kl xl ll lr) r =
3732
+ case go kl xl ll lr of
3733
+ MinView km xm l' -> MinView km xm (balanceR k x l' r)
3734
+
3735
+ maxViewSure :: k -> a -> Map k a -> Map k a -> MaxView k a
3736
+ maxViewSure = go
3737
+ where
3738
+ go k x l Tip = MaxView k x l
3739
+ go k x l (Bin _ kr xr rl rr) =
3740
+ case go kr xr rl rr of
3741
+ MaxView km xm r' -> MaxView km xm (balanceL k x l r')
3677
3742
3678
3743
-- | /O(log n)/. Delete and find the minimal element.
3679
3744
--
3680
3745
-- > deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
3681
3746
-- > deleteFindMin Error: can not return the minimal element of an empty map
3682
3747
3683
3748
deleteFindMin :: Map k a -> ((k ,a ),Map k a )
3684
- deleteFindMin t
3685
- = case t of
3686
- Bin _ k x Tip r -> ((k,x),r)
3687
- Bin _ k x l r -> let ! (km,l') = deleteFindMin l
3688
- ! t' = balanceR k x l' r
3689
- in (km, t')
3690
- Tip -> (error " Map.deleteFindMin: can not return the minimal element of an empty map" , Tip )
3749
+ deleteFindMin t = case minViewWithKey t of
3750
+ Nothing -> (error " Map.deleteFindMin: can not return the minimal element of an empty map" , Tip )
3751
+ Just res -> res
3691
3752
3692
3753
-- | /O(log n)/. Delete and find the maximal element.
3693
3754
--
3694
3755
-- > deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
3695
3756
-- > deleteFindMax empty Error: can not return the maximal element of an empty map
3696
3757
3697
3758
deleteFindMax :: Map k a -> ((k ,a ),Map k a )
3698
- deleteFindMax t
3699
- = case t of
3700
- Bin _ k x l Tip -> ((k,x),l)
3701
- Bin _ k x l r -> let ! (km,r') = deleteFindMax r
3702
- ! t' = balanceL k x l r'
3703
- in (km, t')
3704
- Tip -> (error " Map.deleteFindMax: can not return the maximal element of an empty map" , Tip )
3705
-
3759
+ deleteFindMax t = case maxViewWithKey t of
3760
+ Nothing -> (error " Map.deleteFindMax: can not return the maximal element of an empty map" , Tip )
3761
+ Just res -> res
3706
3762
3707
3763
{- -------------------------------------------------------------------
3708
3764
[balance l x r] balances two trees with value x.
0 commit comments