@@ -1,9 +1,11 @@
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveFunctor #-}
3{-# LANGUAGE DeriveFunctor #-}
4+{-# LANGUAGE FlexibleInstances #-}
4−-- | An 'OMap' behaves much like a 'Map', with mostly the same asymptotics, but
6+-- | An 'OMap' behaves much like a 'M.Map', with mostly the same asymptotics, but
5-- also remembers the order that keys were inserted. All operations whose
7-- also remembers the order that keys were inserted. All operations whose
6−-- asymptotics are worse than 'Map' have documentation saying so.
8+-- asymptotics are worse than 'M.Map' have documentation saying so.
7module Data.Map.Ordered
9module Data.Map.Ordered
9 -- * Trivial maps
11 -- * Trivial maps
@@ -20,6 +22,7 @@ module Data.Map.Ordered
20 -- * If both sides contain the same key, the tuple's value wins
22 -- * If both sides contain the same key, the tuple's value wins
21 , (<|), (|<), (>|), (|>)
23 , (<|), (|<), (>|), (|>)
22 , (<>|), (|<>), unionWithL, unionWithR
24 , (<>|), (|<>), unionWithL, unionWithR
25+ , Bias(Bias, unbiased), L, R
23 -- * Deletion
26 -- * Deletion
24 , delete, filter, (\\)
27 , delete, filter, (\\)
25 , (|/\), (/\|), intersectionWith
28 , (|/\), (/\|), intersectionWith
@@ -29,198 +32,11 @@ module Data.Map.Ordered
29 , Index, findIndex, elemAt
32 , Index, findIndex, elemAt
30 -- * List conversions
33 -- * List conversions
31 , fromList, assocs, toAscList
34 , fromList, assocs, toAscList
35+ -- * 'M.Map' conversion
34−import Control.Applicative ((<|>))
39+import qualified Data.Map as M ()
35−import Control.Monad (guard)
37−import Data.Foldable (Foldable, foldl', foldMap)
38−import Data.Function (on)
39−import Data.Map (Map)
40+import Data.Map.Ordered.Internal
40−import Data.Map.Util (Index, Tag, maxTag, minTag, nextHigherTag, nextLowerTag, readsPrecList, showsPrecList)
41+import Data.Map.Util
41import Prelude hiding (filter, lookup, null)
42import Prelude hiding (filter, lookup, null)
42−import qualified Data.Map as M
44−data OMap k v = OMap !(Map k (Tag, v)) !(Map Tag (k, v))
45− deriving (Functor, Typeable)
47−-- | Values are produced in insertion order, not key order.
48−instance Foldable (OMap k) where foldMap f (OMap _ kvs) = foldMap (f . snd) kvs
49−instance ( Eq k, Eq v) => Eq (OMap k v) where (==) = (==) `on` assocs
50−instance ( Ord k, Ord v) => Ord (OMap k v) where compare = compare `on` assocs
51−instance ( Show k, Show v) => Show (OMap k v) where showsPrec = showsPrecList assocs
52−instance (Ord k, Read k, Read v) => Read (OMap k v) where readsPrec = readsPrecList fromList
54−-- This instance preserves data abstraction at the cost of inefficiency.
55−-- We provide limited reflection services for the sake of data abstraction.
56−instance (Data k, Data a, Ord k) => Data (OMap k a) where
57− gfoldl f z m = z fromList `f` assocs m
58− toConstr _ = fromListConstr
59− gunfold k z c = case constrIndex c of
62− dataTypeOf _ = oMapDataType
65−fromListConstr :: Constr
66−fromListConstr = mkConstr oMapDataType "fromList" [] Prefix
68−oMapDataType :: DataType
69−oMapDataType = mkDataType "Data.Map.Ordered.Map" [fromListConstr]
71−infixr 5 <|, |< -- copy :
73−infixr 6 <>|, |<> -- copy <>
75−(<|) , (|<) :: Ord k => (,) k v -> OMap k v -> OMap k v
76−(>|) , (|>) :: Ord k => OMap k v -> (,) k v -> OMap k v
78−-- | When a key occurs in both maps, prefer the value from the first map.
80−-- See asymptotics of 'unionWithR'.
81−(<>|) :: Ord k => OMap k v -> OMap k v -> OMap k v
83−-- | When a key occurs in both maps, prefer the value from the first map.
85−-- See asymptotics of 'unionWithL'.
86−(|<>) :: Ord k => OMap k v -> OMap k v -> OMap k v
88−(k, v) <| OMap tvs kvs = OMap (M.insert k (t, v) tvs) (M.insert t (k, v) kvs) where
89− t = maybe (nextLowerTag kvs) fst (M.lookup k tvs)
91−(k, v) |< o = OMap (M.insert k (t, v) tvs) (M.insert t (k, v) kvs) where
93− OMap tvs kvs = delete k o
95−o >| (k, v) = OMap (M.insert k (t, v) tvs) (M.insert t (k, v) kvs) where
96− t = nextHigherTag kvs
97− OMap tvs kvs = delete k o
99−OMap tvs kvs |> (k, v) = OMap (M.insert k (t, v) tvs) (M.insert t (k, v) kvs) where
100− t = maybe (nextHigherTag kvs) fst (M.lookup k tvs)
102−(<>|) = unionWithR (const const)
103−(|<>) = unionWithL (const const)
105−-- | Take the union. The first 'OMap' \'s argument's indices are lower than the
106−-- second. If a key appears in both maps, the first argument's index takes
107−-- precedence, and the supplied function is used to combine the values.
109−-- /O(r*log(r))/ where /r/ is the size of the result
110−unionWithL :: Ord k => (k -> v -> v -> v) -> OMap k v -> OMap k v -> OMap k v
111−unionWithL = unionWithInternal (\t t' -> t )
113−-- | Take the union. The first 'OMap' \'s argument's indices are lower than the
114−-- second. If a key appears in both maps, the second argument's index takes
115−-- precedence, and the supplied function is used to combine the values.
117−-- /O(r*log(r))/ where /r/ is the size of the result
118−unionWithR :: Ord k => (k -> v -> v -> v) -> OMap k v -> OMap k v -> OMap k v
119−unionWithR = unionWithInternal (\t t' -> t')
121−unionWithInternal :: Ord k => (Tag -> Tag -> Tag) -> (k -> v -> v -> v) -> OMap k v -> OMap k v -> OMap k v
122−unionWithInternal fT fKV (OMap tvs kvs) (OMap tvs' kvs') = fromTV tvs'' where
123− bump = case maxTag kvs of
126− bump' = case minTag kvs' of
129− tvs'' = M.unionWithKey (\k (t,v) (t',v') -> (fT t t', fKV k v v'))
130− (fmap (\(t,v) -> (bump +t,v)) tvs )
131− (fmap (\(t,v) -> (bump'+t,v)) tvs')
133−-- | @m \\\\ n@ deletes all the keys that exist in @n@ from @m@
135−-- /O(m*log(n))/ where /m/ is the size of the smaller map and /n/ is the size
136−-- of the larger map.
137−(\\) :: Ord k => OMap k v -> OMap k v' -> OMap k v
138−o@(OMap tvs kvs) \\ o'@(OMap tvs' kvs') = if size o < size o'
139− then filter (const . (`notMember` o')) o
140− else foldr delete o (fmap fst (assocs o'))
143−empty = OMap M.empty M.empty
145−singleton :: (k, v) -> OMap k v
146−singleton kv@(k, v) = OMap (M.singleton k (0, v)) (M.singleton 0 kv)
148−-- | If a key appears multiple times, the first occurrence is used for ordering
149−-- and the last occurrence is used for its value. The library author welcomes
150−-- comments on whether this default is sane.
151−fromList :: Ord k => [(k, v)] -> OMap k v
152−fromList = foldl' (|>) empty
154−null :: OMap k v -> Bool
155−null (OMap tvs _) = M.null tvs
157−size :: OMap k v -> Int
158−size (OMap tvs _) = M.size tvs
160−member, notMember :: Ord k => k -> OMap k v -> Bool
161−member k (OMap tvs _) = M.member k tvs
162−notMember k (OMap tvs _) = M.notMember k tvs
164−lookup :: Ord k => k -> OMap k v -> Maybe v
165−lookup k (OMap tvs _) = fmap snd (M.lookup k tvs)
167−-- The Ord constraint is for compatibility with older (<0.5) versions of
169−-- | @filter f m@ contains exactly the key-value pairs of @m@ that satisfy @f@,
170−-- without changing the order they appear
171−filter :: Ord k => (k -> v -> Bool) -> OMap k v -> OMap k v
172−filter f (OMap tvs kvs) = OMap (M.filterWithKey (\k (t, v) -> f k v) tvs)
173− (M.filterWithKey (\t (k, v) -> f k v) kvs)
175−delete :: Ord k => k -> OMap k v -> OMap k v
176−delete k o@(OMap tvs kvs) = case M.lookup k tvs of
178− Just (t, _) -> OMap (M.delete k tvs) (M.delete t kvs)
180−-- | Intersection. (The @/\\@ is intended to look a bit like the standard
181−-- mathematical notation for set intersection.)
183−-- See asymptotics of 'intersectionWith'.
184−(/\|) :: Ord k => OMap k v -> OMap k v' -> OMap k v
185−o /\| o' = intersectionWith (\k v' v -> v) o' o
187−-- | Intersection. (The @/\\@ is intended to look a bit like the standard
188−-- mathematical notation for set intersection.)
190−-- See asymptotics of 'intersectionWith'.
191−(|/\) :: Ord k => OMap k v -> OMap k v' -> OMap k v
192−o |/\ o' = intersectionWith (\k v v' -> v) o o'
194−-- | Take the intersection. The first 'OMap' \'s argument's indices are used for
197−-- /O(m*log(n\/(m+1)) + r*log(r))/ where /m/ is the size of the smaller map, /n/
198−-- is the size of the larger map, and /r/ is the size of the result.
201− (k -> v -> v' -> v'') ->
202− OMap k v -> OMap k v' -> OMap k v''
203−intersectionWith f (OMap tvs kvs) (OMap tvs' kvs') = fromTV
204− $ M.intersectionWithKey (\k (t,v) (t',v') -> (t, f k v v')) tvs tvs'
206−fromTV :: Ord k => Map k (Tag, v) -> OMap k v
207−fromTV tvs = OMap tvs kvs where
208− kvs = M.fromList [(t,(k,v)) | (k,(t,v)) <- M.toList tvs]
210−findIndex :: Ord k => k -> OMap k v -> Maybe Index
211−findIndex k o@(OMap tvs kvs) = do
212− (t, _) <- M.lookup k tvs
215−elemAt :: OMap k v -> Index -> Maybe (k, v)
216−elemAt o@(OMap tvs kvs) i = do
217− guard (0 <= i && i < M.size kvs)
218− return . snd $ M.elemAt i kvs
220−-- | Return key-value pairs in the order they were inserted.
221−assocs :: OMap k v -> [(k, v)]
222−assocs (OMap _ kvs) = map snd $ M.toAscList kvs
224−-- | Return key-value pairs in order of increasing key.
225−toAscList :: OMap k v -> [(k, v)]
226−toAscList (OMap tvs kvs) = map (\(k, (t, v)) -> (k, v)) $ M.toAscList tvs