git.iko.soy/typeable/ordered-containers
on master help sign in
more instances
87708b0Daniel Wagner
Data/Map/Ordered.hs+43−1
@@ -1,5 +1,7 @@
1+{-# LANGUAGE CPP #-}
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveFunctor #-}
3{-# LANGUAGE DeriveFunctor #-}
4+{-# LANGUAGE FlexibleInstances #-}
3
5
4-- | An 'OMap' behaves much like a 'Map', with mostly the same asymptotics, but
6-- | An 'OMap' behaves much like a '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
@@ -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
@@ -37,7 +40,11 @@ import Data.Data
37import Data.Foldable (Foldable, foldl', foldMap)
40import Data.Foldable (Foldable, foldl', foldMap)
38import Data.Function (on)
41import Data.Function (on)
39import Data.Map (Map)
42import Data.Map (Map)
40−import Data.Map.Util (Index, Tag, maxTag, minTag, nextHigherTag, nextLowerTag, readsPrecList, showsPrecList)
43+import Data.Map.Util
44+import Data.Monoid
45+#if MIN_VERSION_base(4,9,0)
46+import Data.Semigroup
47+#endif
41import Prelude hiding (filter, lookup, null)
48import Prelude hiding (filter, lookup, null)
42import qualified Data.Map as M
49import qualified Data.Map as M
43
50
@@ -68,6 +75,37 @@ fromListConstr = mkConstr oMapDataType "fromList" [] Prefix
68oMapDataType :: DataType
75oMapDataType :: DataType
69oMapDataType = mkDataType "Data.Map.Ordered.Map" [fromListConstr]
76oMapDataType = mkDataType "Data.Map.Ordered.Map" [fromListConstr]
70
77
78+#if MIN_VERSION_base(4,9,0)
79+instance (Ord k, Semigroup v) => Semigroup (Bias L (OMap k v)) where
80+ Bias o <> Bias o' = Bias (unionWithL (const (<>)) o o')
81+instance (Ord k, Semigroup v) => Semigroup (Bias R (OMap k v)) where
82+ Bias o <> Bias o' = Bias (unionWithR (const (<>)) o o')
83+#endif
84+
85+-- | Empty maps and map union. When combining two sets that share elements, the
86+-- indices of the left argument are preferred, and the values are combined with
87+-- 'mappend'.
88+--
89+-- See the asymptotics of 'unionWithL'.
90+instance (Ord k, Monoid v) => Monoid (Bias L (OMap k v)) where
91+ mempty = Bias empty
92+ mappend (Bias o) (Bias o') = Bias (unionWithL (const mappend) o o')
93+
94+-- | Empty maps and map union. When combining two sets that share elements, the
95+-- indices of the right argument are preferred, and the values are combined
96+-- with 'mappend'.
97+--
98+-- See the asymptotics of 'unionWithR'.
99+instance (Ord k, Monoid v) => Monoid (Bias R (OMap k v)) where
100+ mempty = Bias empty
101+ mappend (Bias o) (Bias o') = Bias (unionWithR (const mappend) o o')
102+
103+-- | Values are traversed in insertion order, not key order.
104+--
105+-- /O(n*log(n))/ where /n/ is the size of the map.
106+instance Ord k => Traversable (OMap k) where
107+ traverse f (OMap tvs kvs) = fromKV <$> traverse (\(k,v) -> (,) k <$> f v) kvs
108+
71infixr 5 <|, |< -- copy :
109infixr 5 <|, |< -- copy :
72infixl 5 >|, |>
110infixl 5 >|, |>
73infixr 6 <>|, |<> -- copy <>
111infixr 6 <>|, |<> -- copy <>
@@ -207,6 +245,10 @@ fromTV :: Ord k => Map k (Tag, v) -> OMap k v
207fromTV tvs = OMap tvs kvs where
245fromTV tvs = OMap tvs kvs where
208 kvs = M.fromList [(t,(k,v)) | (k,(t,v)) <- M.toList tvs]
246 kvs = M.fromList [(t,(k,v)) | (k,(t,v)) <- M.toList tvs]
209
247
248+fromKV :: Ord k => Map Tag (k, v) -> OMap k v
249+fromKV kvs = OMap tvs kvs where
250+ tvs = M.fromList [(k,(t,v)) | (t,(k,v)) <- M.toList kvs]
251+
210findIndex :: Ord k => k -> OMap k v -> Maybe Index
252findIndex :: Ord k => k -> OMap k v -> Maybe Index
211findIndex k o@(OMap tvs kvs) = do
253findIndex k o@(OMap tvs kvs) = do
212 (t, _) <- M.lookup k tvs
254 (t, _) <- M.lookup k tvs
Data/Map/Util.hs+12
@@ -1,6 +1,10 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE KindSignatures #-}
3+
1module Data.Map.Util where
4module Data.Map.Util where
2
5
3import Data.Map (Map)
6import Data.Map (Map)
7+import Data.Monoid -- so that the docs for Monoid link to the right place
4import qualified Data.Map as M
8import qualified Data.Map as M
5
9
6-- | An internal index used to track ordering only -- its magnitude doesn't
10-- | An internal index used to track ordering only -- its magnitude doesn't
@@ -29,3 +33,11 @@ readsPrecList fromList d = readParen (d > 10) $ \r -> do
29 ("fromList", s) <- lex r
33 ("fromList", s) <- lex r
30 (xs, t) <- reads s
34 (xs, t) <- reads s
31 return (fromList xs, t)
35 return (fromList xs, t)
36+
37+-- | A newtype to hand a 'Monoid' instance on. The phantom first parameter
38+-- tells whether 'mappend' will prefer the indices of its first or second
39+-- argument if there are shared elements in both.
40+newtype Bias (dir :: IndexPreference) a = Bias { unbiased :: a }
41+data IndexPreference = L | R
42+type L = 'L
43+type R = 'R
Data/Set/Ordered.hs+29−1
@@ -1,4 +1,6 @@
1+{-# LANGUAGE CPP #-}
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
3+{-# LANGUAGE FlexibleInstances #-}
2
4
3-- | An 'OSet' behaves much like a 'Set', with mostly the same asymptotics, but
5-- | An 'OSet' behaves much like a 'Set', with mostly the same asymptotics, but
4-- also remembers the order that values were inserted. All operations whose
6-- also remembers the order that values were inserted. All operations whose
@@ -17,6 +19,7 @@ module Data.Set.Ordered
17 -- * The left argument's indices are lower than the right argument's indices
19 -- * The left argument's indices are lower than the right argument's indices
18 , (<|), (|<), (>|), (|>)
20 , (<|), (|<), (>|), (|>)
19 , (<>|), (|<>)
21 , (<>|), (|<>)
22+ , Bias(Bias, unbiased), L, R
20 -- * Query
23 -- * Query
21 , null, size, member, notMember
24 , null, size, member, notMember
22 -- * Deletion
25 -- * Deletion
@@ -32,7 +35,11 @@ import Data.Data
32import Data.Foldable (Foldable, foldl', foldMap, foldr, toList)
35import Data.Foldable (Foldable, foldl', foldMap, foldr, toList)
33import Data.Function (on)
36import Data.Function (on)
34import Data.Map (Map)
37import Data.Map (Map)
35−import Data.Map.Util (Index, Tag, maxTag, minTag, nextHigherTag, nextLowerTag, readsPrecList, showsPrecList)
38+import Data.Map.Util
39+import Data.Monoid
40+#if MIN_VERSION_base(4,9,0)
41+import Data.Semigroup
42+#endif
36import Data.Set (Set) -- so the haddocks link to the right place
43import Data.Set (Set) -- so the haddocks link to the right place
37import Prelude hiding (filter, foldr, lookup, null)
44import Prelude hiding (filter, foldr, lookup, null)
38import qualified Data.Map as M
45import qualified Data.Map as M
@@ -64,6 +71,27 @@ fromListConstr = mkConstr oSetDataType "fromList" [] Prefix
64oSetDataType :: DataType
71oSetDataType :: DataType
65oSetDataType = mkDataType "Data.Set.Ordered.Set" [fromListConstr]
72oSetDataType = mkDataType "Data.Set.Ordered.Set" [fromListConstr]
66
73
74+#if MIN_VERSION_base(4,9,0)
75+instance Ord a => Semigroup (Bias L (OSet a)) where Bias o <> Bias o' = Bias (o |<> o')
76+instance Ord a => Semigroup (Bias R (OSet a)) where Bias o <> Bias o' = Bias (o <>| o')
77+#endif
78+
79+-- | Empty sets and set union. When combining two sets that share elements, the
80+-- indices of the left argument are preferred.
81+--
82+-- See the asymptotics of ('|<>').
83+instance Ord a => Monoid (Bias L (OSet a)) where
84+ mempty = Bias empty
85+ mappend (Bias o) (Bias o') = Bias (o |<> o')
86+
87+-- | Empty sets and set union. When combining two sets that share elements, the
88+-- indices of the right argument are preferred.
89+--
90+-- See the asymptotics of ('<>|').
91+instance Ord a => Monoid (Bias R (OSet a)) where
92+ mempty = Bias empty
93+ mappend (Bias o) (Bias o') = Bias (o <>| o')
94+
67infixr 5 <|, |< -- copy :
95infixr 5 <|, |< -- copy :
68infixl 5 >|, |>
96infixl 5 >|, |>
69infixr 6 <>|, |<> -- copy <>
97infixr 6 <>|, |<> -- copy <>