packages feed

containers 0.5.1.0 → 0.5.2.0

raw patch · 12 files changed

+508/−136 lines, 12 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.Sequence: instance Alternative Seq
+ Data.Sequence: instance Applicative Seq
+ Data.Set: deleteAt :: Int -> Set a -> Set a
+ Data.Set: elemAt :: Int -> Set a -> a
+ Data.Set: findIndex :: Ord a => a -> Set a -> Int
+ Data.Set: lookupIndex :: Ord a => a -> Set a -> Maybe Int
- Data.Set: map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b
+ Data.Set: map :: Ord b => (a -> b) -> Set a -> Set b

Files

Data/IntMap.hs view
@@ -15,8 +15,12 @@ -- An efficient implementation of maps from integer keys to values -- (dictionaries). ----- This module re-exports the value lazy 'Data.IntMap.Lazy' API, plus--- several value strict functions from 'Data.IntMap.Strict'.+-- This module re-exports the value lazy "Data.IntMap.Lazy" API, plus+-- several deprecated value strict functions. Please note that these functions+-- have different strictness properties than those in "Data.IntMap.Strict":+-- they only evaluate the result of the combining function. For example, the+-- default value to 'insertWith'' is only evaluated if the combining function+-- is called and uses it. -- -- These modules are intended to be imported qualified, to avoid name -- clashes with Prelude functions, e.g.@@ -55,26 +59,44 @@     ) where  import Prelude hiding (lookup,map,filter,foldr,foldl,null)+import Data.IntMap.Base (IntMap(..), join, nomatch, zero) import Data.IntMap.Lazy-import qualified Data.IntMap.Strict as S --- | /Deprecated./ As of version 0.5, replaced by 'S.insertWith'.+-- | /Deprecated./ As of version 0.5, replaced by+-- 'Data.IntMap.Strict.insertWith'. ----- /O(log n)/. Same as 'insertWith', but the combining function is--- applied strictly.  This function is deprecated, use 'insertWith' in--- "Data.IntMap.Strict" instead.+-- /O(log n)/. Same as 'insertWith', but the result of the combining function+-- is evaluated to WHNF before inserted to the map. In contrast to+-- 'Data.IntMap.Strict.insertWith', the value argument is not evaluted when not+-- needed by the combining function.+ insertWith' :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a-insertWith' = S.insertWith-{-# INLINE insertWith' #-}+-- We do not reuse Data.IntMap.Strict.insertWith, because it is stricter -- it+-- forces evaluation of the given value.+insertWith' f k x t+  = insertWithKey' (\_ x' y' -> f x' y') k x t --- | /Deprecated./ As of version 0.5, replaced by 'S.insertWithKey'.+-- | /Deprecated./ As of version 0.5, replaced by+-- 'Data.IntMap.Strict.insertWithKey'. ----- /O(log n)/. Same as 'insertWithKey', but the combining function is--- applied strictly.  This function is deprecated, use 'insertWithKey'--- in "Data.IntMap.Strict" instead.+-- /O(log n)/. Same as 'insertWithKey', but the result of the combining+-- function is evaluated to WHNF before inserted to the map. In contrast to+-- 'Data.IntMap.Strict.insertWithKey', the value argument is not evaluted when+-- not needed by the combining function.+ insertWithKey' :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a-insertWithKey' = S.insertWithKey-{-# INLINE insertWithKey' #-}+-- We do not reuse Data.IntMap.Strict.insertWithKey, because it is stricter -- it+-- forces evaluation of the given value.+insertWithKey' f k x t = k `seq`+  case t of+    Bin p m l r+      | nomatch k p m -> join k (Tip k x) p t+      | zero k m      -> Bin p m (insertWithKey' f k x l) r+      | otherwise     -> Bin p m l (insertWithKey' f k x r)+    Tip ky y+      | k==ky         -> Tip k $! f k x y+      | otherwise     -> join k (Tip k x) ky t+    Nil -> Tip k x  -- | /Deprecated./ As of version 0.5, replaced by 'foldr'. --
Data/IntMap/Base.hs view
@@ -227,7 +227,7 @@  #if __GLASGOW_HASKELL__ import Text.Read-import Data.Data (Data(..), mkNoRepType)+import Data.Data (Data(..), Constr, mkConstr, constrIndex, Fixity(Prefix), DataType, mkDataType) #endif  #if __GLASGOW_HASKELL__@@ -342,15 +342,23 @@ --------------------------------------------------------------------}  -- This instance preserves data abstraction at the cost of inefficiency.--- We omit reflection services for the sake of data abstraction.+-- We provide limited reflection services for the sake of data abstraction.  instance Data a => Data (IntMap a) where   gfoldl f z im = z fromList `f` (toList im)-  toConstr _    = error "toConstr"-  gunfold _ _   = error "gunfold"-  dataTypeOf _  = mkNoRepType "Data.IntMap.IntMap"-  dataCast1 f   = gcast1 f+  toConstr _     = fromListConstr+  gunfold k z c  = case constrIndex c of+    1 -> k (z fromList)+    _ -> error "gunfold"+  dataTypeOf _   = intMapDataType+  dataCast1 f    = gcast1 f +fromListConstr :: Constr+fromListConstr = mkConstr intMapDataType "fromList" [] Prefix++intMapDataType :: DataType+intMapDataType = mkDataType "Data.IntMap.Base.IntMap" [fromListConstr]+ #endif  {--------------------------------------------------------------------@@ -1125,13 +1133,17 @@           go (Bin _ _ _ r') = go r'           go Nil            = error "findMax Nil" --- | /O(min(n,W))/. Delete the minimal key. An error is thrown if the IntMap is already empty.--- Note, this is not the same behavior Map.+-- | /O(min(n,W))/. Delete the minimal key. Returns an empty map if the map is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Map.Map' –+-- versions prior to 0.5 threw an error if the 'IntMap' was already empty. deleteMin :: IntMap a -> IntMap a deleteMin = maybe Nil snd . minView --- | /O(min(n,W))/. Delete the maximal key. An error is thrown if the IntMap is already empty.--- Note, this is not the same behavior Map.+-- | /O(min(n,W))/. Delete the maximal key. Returns an empty map if the map is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Map.Map' –+-- versions prior to 0.5 threw an error if the 'IntMap' was already empty. deleteMax :: IntMap a -> IntMap a deleteMax = maybe Nil snd . maxView @@ -2055,59 +2067,23 @@   = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2)) {-# INLINE branchMask #-} -{-----------------------------------------------------------------------  Finding the highest bit (mask) in a word [x] can be done efficiently in-  three ways:-  * convert to a floating point value and the mantissa tells us the-    [log2(x)] that corresponds with the highest bit position. The mantissa-    is retrieved either via the standard C function [frexp] or by some bit-    twiddling on IEEE compatible numbers (float). Note that one needs to-    use at least [double] precision for an accurate mantissa of 32 bit-    numbers.-  * use bit twiddling, a logarithmic sequence of bitwise or's and shifts (bit).-  * use processor specific assembler instruction (asm).--  The most portable way would be [bit], but is it efficient enough?-  I have measured the cycle counts of the different methods on an AMD-  Athlon-XP 1800 (~ Pentium III 1.8Ghz) using the RDTSC instruction:--  highestBitMask: method  cycles-                  ---------------                   frexp   200-                   float    33-                   bit      11-                   asm      12--  highestBit:     method  cycles-                  ---------------                   frexp   195-                   float    33-                   bit      11-                   asm      11--  Wow, the bit twiddling is on today's RISC like machines even faster-  than a single CISC instruction (BSR)!-----------------------------------------------------------------------}+-- The highestBitMask implementation is based on+-- http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2+-- which has been put in the public domain. -{-----------------------------------------------------------------------  [highestBitMask] returns a word where only the highest bit is set.-  It is found by first setting all bits in lower positions than the-  highest bit and than taking an exclusive or with the original value.-  Allthough the function may look expensive, GHC compiles this into-  excellent C code that subsequently compiled into highly efficient-  machine code. The algorithm is derived from Jorg Arndt's FXT library.-----------------------------------------------------------------------}+-- | Return a word where only the highest bit is set. highestBitMask :: Nat -> Nat-highestBitMask x0-  = case (x0 .|. shiftRL x0 1) of-     x1 -> case (x1 .|. shiftRL x1 2) of-      x2 -> case (x2 .|. shiftRL x2 4) of-       x3 -> case (x3 .|. shiftRL x3 8) of-        x4 -> case (x4 .|. shiftRL x4 16) of+highestBitMask x1 = let x2 = x1 .|. x1 `shiftR` 1+                        x3 = x2 .|. x2 `shiftR` 2+                        x4 = x3 .|. x3 `shiftR` 4+                        x5 = x4 .|. x4 `shiftR` 8+                        x6 = x5 .|. x5 `shiftR` 16 #if !(defined(__GLASGOW_HASKELL__) && WORD_SIZE_IN_BITS==32)-         x5 -> case (x5 .|. shiftRL x5 32) of   -- for 64 bit platforms+                        x7 = x6 .|. x6 `shiftR` 32+                     in x7 `xor` (x7 `shiftR` 1)+#else+                     in x6 `xor` (x6 `shiftR` 1) #endif-          x6 -> (x6 `xor` (shiftRL x6 1)) {-# INLINE highestBitMask #-}  
Data/IntSet/Base.hs view
@@ -172,7 +172,7 @@  #if __GLASGOW_HASKELL__ import Text.Read-import Data.Data (Data(..), mkNoRepType)+import Data.Data (Data(..), Constr, mkConstr, constrIndex, Fixity(Prefix), DataType, mkDataType) #endif  #if __GLASGOW_HASKELL__@@ -274,14 +274,22 @@ --------------------------------------------------------------------}  -- This instance preserves data abstraction at the cost of inefficiency.--- We omit reflection services for the sake of data abstraction.+-- We provide limited reflection services for the sake of data abstraction.  instance Data IntSet where   gfoldl f z is = z fromList `f` (toList is)-  toConstr _    = error "toConstr"-  gunfold _ _   = error "gunfold"-  dataTypeOf _  = mkNoRepType "Data.IntSet.IntSet"+  toConstr _     = fromListConstr+  gunfold k z c  = case constrIndex c of+    1 -> k (z fromList)+    _ -> error "gunfold"+  dataTypeOf _   = intSetDataType +fromListConstr :: Constr+fromListConstr = mkConstr intSetDataType "fromList" [] Prefix++intSetDataType :: DataType+intSetDataType = mkDataType "Data.IntSet.Base.IntSet" [fromListConstr]+ #endif  {--------------------------------------------------------------------@@ -808,11 +816,17 @@           find Nil            = error "findMax Nil"  --- | /O(min(n,W))/. Delete the minimal element.+-- | /O(min(n,W))/. Delete the minimal element. Returns an empty set if the set is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Set.Set' –+-- versions prior to 0.5 threw an error if the 'IntSet' was already empty. deleteMin :: IntSet -> IntSet deleteMin = maybe Nil snd . minView --- | /O(min(n,W))/. Delete the maximal element.+-- | /O(min(n,W))/. Delete the maximal element. Returns an empty set if the set is empty.+--+-- Note that this is a change of behaviour for consistency with 'Data.Set.Set' –+-- versions prior to 0.5 threw an error if the 'IntSet' was already empty. deleteMax :: IntSet -> IntSet deleteMax = maybe Nil snd . maxView @@ -1496,8 +1510,21 @@     by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by     Derrick Lehmer and published in 1964 in a book edited by Beckenbach.)" ----------------------------------------------------------------------}-bitcount :: Int -> Word -> Int++-- We want to be able to compile without cabal. Nevertheless+-- #if defined(MIN_VERSION_base) && MIN_VERSION_base(4,5,0)+-- does not work, because if MIN_VERSION_base is undefined,+-- the last condition is syntactically wrong.+#define MIN_VERSION_base_4_5_0 0+#ifdef MIN_VERSION_base #if MIN_VERSION_base(4,5,0)+#undef MIN_VERSION_base_4_5_0+#define MIN_VERSION_base_4_5_0 1+#endif+#endif++bitcount :: Int -> Word -> Int+#if MIN_VERSION_base_4_5_0 bitcount a x = a + popCount x #else bitcount a0 x0 = go a0 x0
Data/Map.hs view
@@ -15,8 +15,13 @@ -- An efficient implementation of ordered maps from keys to values -- (dictionaries). ----- This module re-exports the value lazy 'Data.Map.Lazy' API, plus--- several value strict functions from 'Data.Map.Strict'.+-- This module re-exports the value lazy "Data.Map.Lazy" API, plus+-- several deprecated value strict functions. Please note that these functions+-- have different strictness properties than those in "Data.Map.Strict":+-- they only evaluate the values inserted into the map. For example, the+-- default value to 'insertWith'' is only evaluated if it's used, i.e. because+-- there's no value for the key already or because the higher-order argument+-- that combines the old and new value uses it. -- -- These modules are intended to be imported qualified, to avoid name -- clashes with Prelude functions, e.g.@@ -51,50 +56,103 @@     , foldWithKey     ) where +import Prelude hiding (foldr)+import Data.Map.Base (Map(..), balanceL, balanceR) import Data.Map.Lazy-import qualified Data.Map.Lazy as L-import qualified Data.Map.Strict as S+import Data.StrictPair --- | /Deprecated./ As of version 0.5, replaced by 'S.insertWith'.+-- | /Deprecated./ As of version 0.5, replaced by 'Data.Map.Strict.insertWith'. ----- /O(log n)/. Same as 'insertWith', but the combining function is--- applied strictly.  This is often the most desirable behavior.+-- /O(log n)/. Same as 'insertWith', but the value being inserted to the map is+-- evaluated to WHNF beforehand. In contrast to 'Data.Map.Strict.insertWith',+-- the value argument is not evaluted when not needed. -- -- For example, to update a counter: -- -- > insertWith' (+) k 1 m --+ insertWith' :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a-insertWith' = S.insertWith+-- We do not reuse Data.Map.Strict.insertWith, because it is stricter -- it+-- forces evaluation of the given value. Some people depend on the original+-- behaviour, which forces only the key and the result of combining function.+-- Particularly, people use insertWith' as a strict version of adjust, which+-- requires to use undefined in the place of the value.+insertWith' f = insertWithKey' (\_ x' y' -> f x' y')+#if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE insertWith' #-}+#else+{-# INLINE insertWith' #-}+#endif --- | /Deprecated./ As of version 0.5, replaced by 'S.insertWithKey'.+-- | /Deprecated./ As of version 0.5, replaced by+-- 'Data.Map.Strict.insertWithKey'. ----- /O(log n)/. Same as 'insertWithKey', but the combining function is--- applied strictly.+-- /O(log n)/. Same as 'insertWithKey', but the value being inserted to the map is+-- evaluated to WHNF beforehand. In contrast to 'Data.Map.Strict.insertWithKey',+-- the value argument is not evaluted when not needed.+ insertWithKey' :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a-insertWithKey' = S.insertWithKey+-- We do not reuse Data.Map.Strict.insertWithKey, because it is stricter -- it+-- forces evaluation of the given value.+insertWithKey' = go+  where+    go :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a+    go _ kx _ _ | kx `seq` False = undefined+    go _ kx x Tip = x `seq` singleton kx x+    go f kx x (Bin sy ky y l r) =+        case compare kx ky of+            LT -> balanceL ky y (go f kx x l) r+            GT -> balanceR ky y l (go f kx x r)+            EQ -> let x' = f kx x y+                  in x' `seq` Bin sy kx x' l r+#if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE insertWithKey' #-}+#else+{-# INLINE insertWithKey' #-}+#endif  -- | /Deprecated./ As of version 0.5, replaced by--- 'S.insertLookupWithKey'.+-- 'Data.Map.Strict.insertLookupWithKey'. ----- /O(log n)/. A strict version of 'insertLookupWithKey'.+-- /O(log n)/. Same as 'insertLookupWithKey', but the value being inserted to+-- the map is evaluated to WHNF beforehand. In contrast to+-- 'Data.Map.Strict.insertLookupWithKey', the value argument is not evaluted+-- when not needed.+ insertLookupWithKey' :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a                      -> (Maybe a, Map k a)-insertLookupWithKey' = S.insertLookupWithKey+-- We do not reuse Data.Map.Strict.insertLookupWithKey, because it is stricter -- it+-- forces evaluation of the given value.+insertLookupWithKey' f0 kx0 x0 t0 = toPair $ go f0 kx0 x0 t0+  where+    go :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> StrictPair (Maybe a) (Map k a)+    go _ kx _ _ | kx `seq` False = undefined+    go _ kx x Tip = x `seq` Nothing :*: singleton kx x+    go f kx x (Bin sy ky y l r) =+        case compare kx ky of+            LT -> let (found :*: l') = go f kx x l+                  in found :*: balanceL ky y l' r+            GT -> let (found :*: r') = go f kx x r+                  in found :*: balanceR ky y l r'+            EQ -> let x' = f kx x y+                  in x' `seq` (Just y :*: Bin sy kx x' l r)+#if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE insertLookupWithKey' #-}+#else+{-# INLINE insertLookupWithKey' #-}+#endif --- | /Deprecated./ As of version 0.5, replaced by 'L.foldr'.+-- | /Deprecated./ As of version 0.5, replaced by 'foldr'. -- -- /O(n)/. Fold the values in the map using the given right-associative -- binary operator. This function is an equivalent of 'foldr' and is present -- for compatibility only. fold :: (a -> b -> b) -> b -> Map k a -> b-fold = L.foldr+fold = foldr {-# INLINE fold #-} --- | /Deprecated./ As of version 0.4, replaced by 'L.foldrWithKey'.+-- | /Deprecated./ As of version 0.4, replaced by 'foldrWithKey'. -- -- /O(n)/. Fold the keys and values in the map using the given right-associative -- binary operator. This function is an equivalent of 'foldrWithKey' and is present
Data/Map/Base.hs view
@@ -335,15 +335,23 @@ --------------------------------------------------------------------}  -- This instance preserves data abstraction at the cost of inefficiency.--- We omit reflection services for the sake of data abstraction.+-- We provide limited reflection services for the sake of data abstraction.  instance (Data k, Data a, Ord k) => Data (Map k a) where   gfoldl f z m   = z fromList `f` toList m-  toConstr _     = error "toConstr"-  gunfold _ _    = error "gunfold"-  dataTypeOf _   = mkNoRepType "Data.Map.Map"+  toConstr _     = fromListConstr+  gunfold k z c  = case constrIndex c of+    1 -> k (z fromList)+    _ -> error "gunfold"+  dataTypeOf _   = mapDataType   dataCast2 f    = gcast2 f +fromListConstr :: Constr+fromListConstr = mkConstr mapDataType "fromList" [] Prefix++mapDataType :: DataType+mapDataType = mkDataType "Data.Map.Base.Map" [fromListConstr]+ #endif  {--------------------------------------------------------------------@@ -912,9 +920,10 @@ {--------------------------------------------------------------------   Indexing --------------------------------------------------------------------}--- | /O(log n)/. Return the /index/ of a key. The index is a number from--- /0/ up to, but not including, the 'size' of the map. Calls 'error' when--- the key is not a 'member' of the map.+-- | /O(log n)/. Return the /index/ of a key, which is its zero-based index in+-- the sequence sorted by keys. The index is a number from /0/ up to, but not+-- including, the 'size' of the map. Calls 'error' when the key is not+-- a 'member' of the map. -- -- > findIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map -- > findIndex 3 (fromList [(5,"a"), (3,"b")]) == 0@@ -937,8 +946,9 @@ {-# INLINABLE findIndex #-} #endif --- | /O(log n)/. Lookup the /index/ of a key. The index is a number from--- /0/ up to, but not including, the 'size' of the map.+-- | /O(log n)/. Lookup the /index/ of a key, which is its zero-based index in+-- the sequence sorted by keys. The index is a number from /0/ up to, but not+-- including, the 'size' of the map. -- -- > isJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False -- > fromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0@@ -961,8 +971,9 @@ {-# INLINABLE lookupIndex #-} #endif --- | /O(log n)/. Retrieve an element by /index/. Calls 'error' when an--- invalid index is used.+-- | /O(log n)/. Retrieve an element by its /index/, i.e. by its zero-based+-- index in the sequence sorted by keys. If the /index/ is out of range (less+-- than zero, greater or equal to 'size' of the map), 'error' is called. -- -- > elemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b") -- > elemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")@@ -979,8 +990,9 @@   where     sizeL = size l --- | /O(log n)/. Update the element at /index/. Calls 'error' when an--- invalid index is used.+-- | /O(log n)/. Update the element at /index/, i.e. by its zero-based index in+-- the sequence sorted by keys. If the /index/ is out of range (less than zero,+-- greater or equal to 'size' of the map), 'error' is called. -- -- > updateAt (\ _ _ -> Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")] -- > updateAt (\ _ _ -> Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]@@ -1004,8 +1016,9 @@       where         sizeL = size l --- | /O(log n)/. Delete the element at /index/.--- Defined as (@'deleteAt' i map = 'updateAt' (\k x -> 'Nothing') i map@).+-- | /O(log n)/. Delete the element at /index/, i.e. by its zero-based index in+-- the sequence sorted by keys. If the /index/ is out of range (less than zero,+-- greater or equal to 'size' of the map), 'error' is called. -- -- > deleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a" -- > deleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"@@ -1191,7 +1204,6 @@ -- It prefers @t1@ when duplicate keys are encountered, -- i.e. (@'union' == 'unionWith' 'const'@). -- The implementation uses the efficient /hedge-union/ algorithm.--- Hedge-union is more efficient on (bigset \``union`\` smallset). -- -- > union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")] @@ -1232,7 +1244,6 @@  -- | /O(n+m)/. -- Union with a combining function. The implementation uses the efficient /hedge-union/ algorithm.--- Hedge-union is more efficient on (bigset \``union`\` smallset). -- -- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value -- > unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]@@ -1311,6 +1322,8 @@ -- | /O(n+m)/. Intersection of two maps. -- Return data in the first map for the keys existing in both maps. -- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).+-- The implementation uses an efficient /hedge/ algorithm comparable with+-- /hedge-union/. -- -- > intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a" @@ -1333,7 +1346,8 @@ {-# INLINABLE hedgeInt #-} #endif --- | /O(n+m)/. Intersection with a combining function.+-- | /O(n+m)/. Intersection with a combining function.  The implementation uses+-- an efficient /hedge/ algorithm comparable with /hedge-union/. -- -- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA" @@ -1344,8 +1358,8 @@ {-# INLINABLE intersectionWith #-} #endif --- | /O(n+m)/. Intersection with a combining function.--- Intersection is more efficient on (bigset \``intersection`\` smallset).+-- | /O(n+m)/. Intersection with a combining function.  The implementation uses+-- an efficient /hedge/ algorithm comparable with /hedge-union/. -- -- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar -- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
Data/Map/Strict.hs view
@@ -713,7 +713,6 @@  -- | /O(n+m)/. -- Union with a combining function. The implementation uses the efficient /hedge-union/ algorithm.--- Hedge-union is more efficient on (bigset \``union`\` smallset). -- -- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value -- > unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]@@ -767,7 +766,8 @@   Intersection --------------------------------------------------------------------} --- | /O(n+m)/. Intersection with a combining function.+-- | /O(n+m)/. Intersection with a combining function.  The implementation uses+-- an efficient /hedge/ algorithm comparable with /hedge-union/. -- -- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA" @@ -778,8 +778,8 @@ {-# INLINABLE intersectionWith #-} #endif --- | /O(n+m)/. Intersection with a combining function.--- Intersection is more efficient on (bigset \``intersection`\` smallset).+-- | /O(n+m)/. Intersection with a combining function.  The implementation uses+-- an efficient /hedge/ algorithm comparable with /hedge-union/. -- -- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar -- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
Data/Sequence.hs view
@@ -142,7 +142,9 @@     scanl, scanl1, scanr, scanr1, replicate, zip, zipWith, zip3, zipWith3,     takeWhile, dropWhile, iterate, reverse, filter, mapM, sum, all) import qualified Data.List-import Control.Applicative (Applicative(..), (<$>), WrappedMonad(..), liftA, liftA2, liftA3)+import Control.Applicative (Applicative(..), (<$>), Alternative,+                            WrappedMonad(..), liftA, liftA2, liftA3)+import qualified Control.Applicative as Applicative (Alternative(..)) import Control.DeepSeq (NFData(rnf)) import Control.Monad (MonadPlus(..), ap) import Data.Monoid (Monoid(..))@@ -198,9 +200,18 @@     xs >>= f = foldl' add empty xs       where add ys x = ys >< f x +instance Applicative Seq where+    pure = singleton+    fs <*> xs = foldl' add empty fs+      where add ys f = ys >< fmap f xs+ instance MonadPlus Seq where     mzero = empty     mplus = (><)++instance Alternative Seq where+    empty = empty+    (<|>) = (><)  instance Eq a => Eq (Seq a) where     xs == ys = length xs == length ys && toList xs == toList ys
Data/Set.hs view
@@ -81,6 +81,12 @@             , split             , splitMember +            -- * Indexed+            , lookupIndex+            , findIndex+            , elemAt+            , deleteAt+             -- * Map             , S.map             , mapMonotonic
Data/Set/Base.hs view
@@ -127,6 +127,12 @@             , split             , splitMember +            -- * Indexed+            , lookupIndex+            , findIndex+            , elemAt+            , deleteAt+             -- * Map             , map             , mapMonotonic@@ -197,6 +203,7 @@ -- want the compilers to be compiled by as many compilers as possible. #define STRICT_1_OF_2(fn) fn arg _ | arg `seq` False = undefined #define STRICT_1_OF_3(fn) fn arg _ _ | arg `seq` False = undefined+#define STRICT_2_OF_3(fn) fn _ arg _ | arg `seq` False = undefined  {--------------------------------------------------------------------   Operators@@ -241,15 +248,23 @@ --------------------------------------------------------------------}  -- This instance preserves data abstraction at the cost of inefficiency.--- We omit reflection services for the sake of data abstraction.+-- We provide limited reflection services for the sake of data abstraction.  instance (Data a, Ord a) => Data (Set a) where   gfoldl f z set = z fromList `f` (toList set)-  toConstr _     = error "toConstr"-  gunfold _ _    = error "gunfold"-  dataTypeOf _   = mkNoRepType "Data.Set.Set"+  toConstr _     = fromListConstr+  gunfold k z c  = case constrIndex c of+    1 -> k (z fromList)+    _ -> error "gunfold"+  dataTypeOf _   = setDataType   dataCast1 f    = gcast1 f +fromListConstr :: Constr+fromListConstr = mkConstr setDataType "fromList" [] Prefix++setDataType :: DataType+setDataType = mkDataType "Data.Set.Base.Set" [fromListConstr]+ #endif  {--------------------------------------------------------------------@@ -510,13 +525,13 @@ findMax (Bin _ _ _ r)    = findMax r findMax Tip              = error "Set.findMax: empty set has no maximal element" --- | /O(log n)/. Delete the minimal element.+-- | /O(log n)/. Delete the minimal element. Returns an empty set if the set is empty. deleteMin :: Set a -> Set a deleteMin (Bin _ _ Tip r) = r deleteMin (Bin _ x l r)   = balanceR x (deleteMin l) r deleteMin Tip             = Tip --- | /O(log n)/. Delete the maximal element.+-- | /O(log n)/. Delete the maximal element. Returns an empty set if the set is empty. deleteMax :: Set a -> Set a deleteMax (Bin _ _ l Tip) = l deleteMax (Bin _ x l r)   = balanceL x l (deleteMax r)@@ -535,7 +550,6 @@ -- | /O(n+m)/. The union of two sets, preferring the first set when -- equal elements are encountered. -- The implementation uses the efficient /hedge-union/ algorithm.--- Hedge-union is more efficient on (bigset `union` smallset). union :: Ord a => Set a -> Set a -> Set a union Tip t2  = t2 union t1 Tip  = t1@@ -582,8 +596,9 @@ {--------------------------------------------------------------------   Intersection --------------------------------------------------------------------}--- | /O(n+m)/. The intersection of two sets.--- Elements of the result come from the first set, so for example+-- | /O(n+m)/. The intersection of two sets.  The implementation uses an+-- efficient /hedge/ algorithm comparable with /hedge-union/.  Elements of the+-- result come from the first set, so for example -- -- > import qualified Data.Set as S -- > data AB = A | B deriving Show@@ -644,7 +659,7 @@ -- It's worth noting that the size of the result may be smaller if, -- for some @(x,y)@, @x \/= y && f x == f y@ -map :: (Ord a, Ord b) => (a->b) -> Set a -> Set b+map :: Ord b => (a->b) -> Set a -> Set b map f = fromList . List.map f . toList #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE map #-}@@ -1032,6 +1047,101 @@ #if __GLASGOW_HASKELL__ >= 700 {-# INLINABLE splitMember #-} #endif++{--------------------------------------------------------------------+  Indexing+--------------------------------------------------------------------}++-- | /O(log n)/. Return the /index/ of an element, which is its zero-based+-- index in the sorted sequence of elements. The index is a number from /0/ up+-- to, but not including, the 'size' of the set. Calls 'error' when the element+-- is not a 'member' of the set.+--+-- > findIndex 2 (fromList [5,3])    Error: element is not in the set+-- > findIndex 3 (fromList [5,3]) == 0+-- > findIndex 5 (fromList [5,3]) == 1+-- > findIndex 6 (fromList [5,3])    Error: element is not in the set++-- See Note: Type of local 'go' function+findIndex :: Ord a => a -> Set a -> Int+findIndex = go 0+  where+    go :: Ord a => Int -> a -> Set a -> Int+    STRICT_1_OF_3(go)+    STRICT_2_OF_3(go)+    go _   _ Tip  = error "Set.findIndex: element is not in the set"+    go idx x (Bin _ kx l r) = case compare x kx of+      LT -> go idx x l+      GT -> go (idx + size l + 1) x r+      EQ -> idx + size l+#if __GLASGOW_HASKELL__ >= 700+{-# INLINABLE findIndex #-}+#endif++-- | /O(log n)/. Lookup the /index/ of an element, which is its zero-based index in+-- the sorted sequence of elements. The index is a number from /0/ up to, but not+-- including, the 'size' of the set.+--+-- > isJust   (lookupIndex 2 (fromList [5,3])) == False+-- > fromJust (lookupIndex 3 (fromList [5,3])) == 0+-- > fromJust (lookupIndex 5 (fromList [5,3])) == 1+-- > isJust   (lookupIndex 6 (fromList [5,3])) == False++-- See Note: Type of local 'go' function+lookupIndex :: Ord a => a -> Set a -> Maybe Int+lookupIndex = go 0+  where+    go :: Ord a => Int -> a -> Set a -> Maybe Int+    STRICT_1_OF_3(go)+    STRICT_2_OF_3(go)+    go _   _ Tip  = Nothing+    go idx x (Bin _ kx l r) = case compare x kx of+      LT -> go idx x l+      GT -> go (idx + size l + 1) x r+      EQ -> Just $! idx + size l+#if __GLASGOW_HASKELL__ >= 700+{-# INLINABLE lookupIndex #-}+#endif++-- | /O(log n)/. Retrieve an element by its /index/, i.e. by its zero-based+-- index in the sorted sequence of elements. If the /index/ is out of range (less+-- than zero, greater or equal to 'size' of the set), 'error' is called.+--+-- > elemAt 0 (fromList [5,3]) == 3+-- > elemAt 1 (fromList [5,3]) == 5+-- > elemAt 2 (fromList [5,3])    Error: index out of range++elemAt :: Int -> Set a -> a+STRICT_1_OF_2(elemAt)+elemAt _ Tip = error "Set.elemAt: index out of range"+elemAt i (Bin _ x l r)+  = case compare i sizeL of+      LT -> elemAt i l+      GT -> elemAt (i-sizeL-1) r+      EQ -> x+  where+    sizeL = size l++-- | /O(log n)/. Delete the element at /index/, i.e. by its zero-based index in+-- the sorted sequence of elements. If the /index/ is out of range (less than zero,+-- greater or equal to 'size' of the set), 'error' is called.+--+-- > deleteAt 0    (fromList [5,3]) == singleton 5+-- > deleteAt 1    (fromList [5,3]) == singleton 3+-- > deleteAt 2    (fromList [5,3])    Error: index out of range+-- > deleteAt (-1) (fromList [5,3])    Error: index out of range++deleteAt :: Int -> Set a -> Set a+deleteAt i t = i `seq`+  case t of+    Tip -> error "Set.deleteAt: index out of range"+    Bin _ x l r -> case compare i sizeL of+      LT -> balanceR x (deleteAt i l) r+      GT -> balanceL x l (deleteAt (i-sizeL-1) r)+      EQ -> glue l r+      where+        sizeL = size l+  {--------------------------------------------------------------------   Utility functions that maintain the balance properties of the tree.
containers.cabal view
@@ -1,5 +1,5 @@ name: containers-version: 0.5.1.0+version: 0.5.2.0 license: BSD3 license-file: LICENSE maintainer: fox@ucw.cz@@ -175,6 +175,21 @@         QuickCheck,         test-framework,         test-framework-hunit,+        test-framework-quickcheck2++Test-suite deprecated-properties+    hs-source-dirs: tests, .+    main-is: deprecated-properties.hs+    type: exitcode-stdio-1.0+    cpp-options: -DTESTING++    build-depends: base >= 4.2 && < 5, array, deepseq >= 1.2 && < 1.4, ghc-prim+    ghc-options: -O2+    extensions: MagicHash, DeriveDataTypeable, StandaloneDeriving, Rank2Types++    build-depends:+        QuickCheck,+        test-framework,         test-framework-quickcheck2  Test-suite seq-properties
+ tests/deprecated-properties.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE CPP #-}++-- This module tests the deprecated properties of Data.Map and Data.IntMap,+-- because these cannot be tested in either map-properties or+-- intmap-properties, as these modules are designed to work with the .Lazy and+-- .Strict modules.++import qualified Data.Map as M+import qualified Data.Map.Strict as SM+import qualified Data.IntMap as IM+import qualified Data.IntMap.Strict as SIM++import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Text.Show.Functions ()++default (Int)++main :: IO ()+main = defaultMain+         [ testProperty "Data.Map.insertWith' as Strict.insertWith" prop_mapInsertWith'Strict+         , testProperty "Data.Map.insertWith' undefined value" prop_mapInsertWith'Undefined+         , testProperty "Data.Map.insertWithKey' as Strict.insertWithKey" prop_mapInsertWithKey'Strict+         , testProperty "Data.Map.insertWithKey' undefined value" prop_mapInsertWithKey'Undefined+         , testProperty "Data.Map.insertLookupWithKey' as Strict.insertLookupWithKey" prop_mapInsertLookupWithKey'Strict+         , testProperty "Data.Map.insertLookupWithKey' undefined value" prop_mapInsertLookupWithKey'Undefined+         , testProperty "Data.IntMap.insertWith' as Strict.insertWith" prop_intmapInsertWith'Strict+         , testProperty "Data.IntMap.insertWith' undefined value" prop_intmapInsertWith'Undefined+         , testProperty "Data.IntMap.insertWithKey' as Strict.insertWithKey" prop_intmapInsertWithKey'Strict+         , testProperty "Data.IntMap.insertWithKey' undefined value" prop_intmapInsertWithKey'Undefined+         ]+++---------- Map properties ----------++prop_mapInsertWith'Strict :: [(Int, Int)] -> (Int -> Int -> Int) -> [(Int, Int)] -> Bool+prop_mapInsertWith'Strict xs f kxxs =+  let m = M.fromList xs+      insertList ins = foldr (\(kx, x) -> ins f kx x) m kxxs+  in insertList M.insertWith' == insertList SM.insertWith++prop_mapInsertWith'Undefined :: [(Int, Int)] -> Bool+prop_mapInsertWith'Undefined xs =+  let m = M.fromList xs+      f _ x = x * 33+      insertList ins = foldr (\(kx, _) -> ins f kx undefined) m xs+  in insertList M.insertWith' == insertList M.insertWith++prop_mapInsertWithKey'Strict :: [(Int, Int)] -> (Int -> Int -> Int -> Int) -> [(Int, Int)] -> Bool+prop_mapInsertWithKey'Strict xs f kxxs =+  let m = M.fromList xs+      insertList ins = foldr (\(kx, x) -> ins f kx x) m kxxs+  in insertList M.insertWithKey' == insertList SM.insertWithKey++prop_mapInsertWithKey'Undefined :: [(Int, Int)] -> Bool+prop_mapInsertWithKey'Undefined xs =+  let m = M.fromList xs+      f k _ x = (k + x) * 33+      insertList ins = foldr (\(kx, _) -> ins f kx undefined) m xs+  in insertList M.insertWithKey' == insertList M.insertWithKey++prop_mapInsertLookupWithKey'Strict :: [(Int, Int)] -> (Int -> Int -> Int -> Int) -> [(Int, Int)] -> Bool+prop_mapInsertLookupWithKey'Strict xs f kxxs =+  let m = M.fromList xs+      insertLookupList insLkp = scanr (\(kx, x) (_, mp) -> insLkp f kx x mp) (Nothing, m) kxxs+  in insertLookupList M.insertLookupWithKey' == insertLookupList SM.insertLookupWithKey++prop_mapInsertLookupWithKey'Undefined :: [(Int, Int)] -> Bool+prop_mapInsertLookupWithKey'Undefined xs =+  let m = M.fromList xs+      f k _ x = (k + x) * 33+      insertLookupList insLkp = scanr (\(kx, _) (_, mp) -> insLkp f kx undefined mp) (Nothing, m) xs+  in insertLookupList M.insertLookupWithKey' == insertLookupList M.insertLookupWithKey+++---------- IntMap properties ----------++prop_intmapInsertWith'Strict :: [(Int, Int)] -> (Int -> Int -> Int) -> [(Int, Int)] -> Bool+prop_intmapInsertWith'Strict xs f kxxs =+  let m = IM.fromList xs+      insertList ins = foldr (\(kx, x) -> ins f kx x) m kxxs+  in insertList IM.insertWith' == insertList SIM.insertWith++prop_intmapInsertWith'Undefined :: [(Int, Int)] -> Bool+prop_intmapInsertWith'Undefined xs =+  let m = IM.fromList xs+      f _ x = x * 33+      insertList ins = foldr (\(kx, _) -> ins f kx undefined) m xs+  in insertList IM.insertWith' == insertList IM.insertWith++prop_intmapInsertWithKey'Strict :: [(Int, Int)] -> (Int -> Int -> Int -> Int) -> [(Int, Int)] -> Bool+prop_intmapInsertWithKey'Strict xs f kxxs =+  let m = IM.fromList xs+      insertList ins = foldr (\(kx, x) -> ins f kx x) m kxxs+  in insertList IM.insertWithKey' == insertList SIM.insertWithKey++prop_intmapInsertWithKey'Undefined :: [(Int, Int)] -> Bool+prop_intmapInsertWithKey'Undefined xs =+  let m = IM.fromList xs+      f k _ x = (k + x) * 33+      insertList ins = foldr (\(kx, _) -> ins f kx undefined) m xs+  in insertList IM.insertWithKey' == insertList IM.insertWithKey
tests/set-properties.hs view
@@ -2,6 +2,7 @@ import Data.List (nub,sort) import qualified Data.List as List import Data.Monoid (mempty)+import Data.Maybe import Data.Set import Prelude hiding (lookup, null, map, filter, foldr, foldl) import Test.Framework@@ -15,6 +16,10 @@                    , testCase "lookupGT" test_lookupGT                    , testCase "lookupLE" test_lookupLE                    , testCase "lookupGE" test_lookupGE+                   , testCase "lookupIndex" test_lookupIndex+                   , testCase "findIndex" test_findIndex+                   , testCase "elemAt" test_elemAt+                   , testCase "deleteAt" test_deleteAt                    , testProperty "prop_Valid" prop_Valid                    , testProperty "prop_Single" prop_Single                    , testProperty "prop_Member" prop_Member@@ -88,6 +93,32 @@    lookupGE 3 (fromList [3, 5]) @?= Just 3    lookupGE 4 (fromList [3, 5]) @?= Just 5    lookupGE 6 (fromList [3, 5]) @?= Nothing++{--------------------------------------------------------------------+  Indexed+--------------------------------------------------------------------}++test_lookupIndex :: Assertion+test_lookupIndex = do+    isJust   (lookupIndex 2 (fromList [5,3])) @?= False+    fromJust (lookupIndex 3 (fromList [5,3])) @?= 0+    fromJust (lookupIndex 5 (fromList [5,3])) @?= 1+    isJust   (lookupIndex 6 (fromList [5,3])) @?= False++test_findIndex :: Assertion+test_findIndex = do+    findIndex 3 (fromList [5,3]) @?= 0+    findIndex 5 (fromList [5,3]) @?= 1++test_elemAt :: Assertion+test_elemAt = do+    elemAt 0 (fromList [5,3]) @?= 3+    elemAt 1 (fromList [5,3]) @?= 5++test_deleteAt :: Assertion+test_deleteAt = do+    deleteAt 0 (fromList [5,3]) @?= singleton 5+    deleteAt 1 (fromList [5,3]) @?= singleton 3  {--------------------------------------------------------------------   Arbitrary, reasonably balanced trees