packages feed

Map 0.1.3.2 → 0.1.3.3

raw patch · 2 files changed

+67/−8 lines, 2 filesdep ~filtrablePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: filtrable

API changes (from Hackage documentation)

- Data.Map.Class: instance Data.Filtrable.Filtrable (Data.Map.Internal.Map key)
- Data.Map.Class: instance Data.Filtrable.Filtrable Data.IntMap.Internal.IntMap

Files

Data/Map/Class.hs view
@@ -1,3 +1,6 @@+-- | Class of key-value maps+--+-- See 'StaticMap' and 'Map'. module Data.Map.Class where  import Control.Applicative hiding (Alternative (..))@@ -18,32 +21,47 @@ import Util ((∘), (∘∘), compose2, bind2) import Util.Private (Endo (..)) +-- | Class of key-value maps+--+-- Laws:+--+-- * @'adjustA' 'pure' _ = 'pure'@+--+-- * @'adjustA' 'Const' k '<=<' 'traverseWithKey' f = 'fmap' 'Const' '.' f k '<=<' 'getConst' '.' 'adjustA' 'Const' k@ class Traversable map => StaticMap map where     type Key map+    -- | Modify the value of the key in the map. If the key is absent, the map is returned unmodified.     adjustA :: Applicative p => (a -> p a) -> Key map -> map a -> p (map a)+    -- | Traverse a function over each value in the map.     traverseWithKey :: (Applicative p) => (Key map -> a -> p b) -> map a -> p (map b) +-- | Class of key-value maps with variable structure class (Filtrable map, StaticMap map) => Map map where+    -- | The empty map     empty :: map a+    -- | Modify the value of the key in the map, or insert the key and its value into the map, or delete the key and its value from the map, functorially.+    --+    -- @fmap ('!?' k) . 'alterF' f k = f . ('!?' k)@+    --+    -- This is the most general operation on a given key in the map.     alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key map -> map a -> f (map a)+    -- | Combine two maps with the given function, which is called once for each key present in either map, inclusive.     mergeA :: Applicative p => (Key map -> Either' a b -> p (Maybe c)) -> map a -> map b -> p (map c)+    -- | Traverse a function over each value in the map, gathering the 'Just' values and forgetting the 'Nothing'.     mapMaybeWithKeyA :: Applicative p => (Key map -> a -> p (Maybe b)) -> map a -> p (map b)+    -- | Traverse a function over each value in the map, gathering the 'Left' and 'Right' values separately.     mapEitherWithKeyA :: Applicative p => (Key map -> a -> p (Either b c)) -> map a -> p (map b, map c)     mapEitherWithKeyA f = liftA2 (,) <$> mapMaybeWithKeyA (fmap (Just `either` pure Nothing) ∘∘ f)                                      <*> mapMaybeWithKeyA (fmap (pure Nothing `either` Just) ∘∘ f) +-- | Default implementation of `adjustA` in terms of `Map` methods defaultAdjustA :: (Map map, Applicative p) => (a -> p a) -> Key map -> map a -> p (map a) defaultAdjustA f = alterF (traverse f) +-- | Default implementation of `traverseWithKey` in terms of `Map` methods defaultTraverseWithKey :: (Map map, Applicative p) => (Key map -> a -> p b) -> map a -> p (map b) defaultTraverseWithKey f = mapMaybeWithKeyA (fmap Just ∘∘ f) -instance Filtrable IntMap where-    mapMaybe = Int.mapMaybe--instance Filtrable (M.Map key) where-    mapMaybe = M.mapMaybe- instance StaticMap Maybe where     type Key Maybe = ()     adjustA f () = traverse f@@ -114,49 +132,67 @@     mergeA f (Pair a₀ b₀) (Pair a₁ b₁) = Pair <$> mergeA (f . Left) a₀ a₁ <*> mergeA (f . Right) b₀ b₁     mapMaybeWithKeyA f (Pair a b) = Pair <$> mapMaybeWithKeyA (f . Left) a <*> mapMaybeWithKeyA (f . Right) b +-- | Look up the key in the map. infix 9 !? (!?) :: StaticMap map => map a -> Key map -> Maybe a (!?) = flip $ getLast ∘∘ fst ∘∘ adjustA ((,) <$> Last . Just <*> id) +-- | Insert a key and new value into the map, the new value clobbering the old if the key is already present.+-- @'insert' = 'insertWith' 'pure'@ insert :: Map map => Key map -> a -> map a -> map a insert = insertWith pure +-- | Insert a key and new value into the map, combining the old and new values with the given function if the key is already present. insertWith :: Map map => (a -> a -> a) -> Key map -> a -> map a -> map a insertWith f = flip $ \ a -> alter (Just . maybe a (f a)) +-- | Insert a key and new value into the map, looking up the old value if the key is already present. insertLookup :: Map map => Key map -> a -> map a -> (Maybe a, map a) insertLookup = insertLookupWith pure +-- | Insert a key and new value into the map, looking up the old value and combining the old and new values with the given function if the key is already present. insertLookupWith :: Map map => (a -> a -> a) -> Key map -> a -> map a -> (Maybe a, map a) insertLookupWith f = flip $ \ a -> alterLookup (Just . maybe a (f a)) +-- | Delete a key and its value from the map. If the key is absent, the map is returned unmodified. delete :: Map map => Key map -> map a -> map a delete = alter (pure Nothing) +-- | Modify the value of the key in the map. If the key is absent, the map is returned unmodified. adjust :: StaticMap map => (a -> a) -> Key map -> map a -> map a adjust f = runIdentity ∘∘ adjustA (pure . f) +-- | Modify the value of the key in the map, or delete the key and its value from the map, if the given function returns 'Just' or 'Nothing', in turn. If the key is absent, the map is returned unmodified. update :: Map map => (a -> Maybe a) -> Key map -> map a -> map a update f = alter (>>= f) +-- | Modify the value of the key in the map, or delete the key and its value from the map, if the given function returns 'Just' or 'Nothing', in turn, looking up the old value if the key is already present. If the key is absent, the map is returned unmodified. updateLookup :: Map map => (a -> Maybe a) -> Key map -> map a -> (Maybe a, map a) updateLookup f = alterLookup (>>= f) +-- | Modify the value of the key in the map, or insert the key and its value into the map, or delete the key and its value from the map. alter :: Map map => (Maybe a -> Maybe a) -> Key map -> map a -> map a alter f = runIdentity ∘∘ alterF (Identity . f) +-- | Modify the value of the key in the map, or insert the key and its value into the map, or delete the key and its value from the map, looking up the old value if the key is already present. alterLookup :: Map map => (Maybe a -> Maybe a) -> Key map -> map a -> (Maybe a, map a) alterLookup f = alterF ((,) <*> f) +-- | Modify the value of the key in the map, or insert the key and its value into the map, or delete the key and its value from the map, looking up the old value if the key is already present, functorially.+--+-- This is no more general than `alterF`, but is defined for convenience. alterLookupF :: (Map map, Functor f) => (Maybe a -> f (Maybe a)) -> Key map -> map a -> f (Maybe a, map a) alterLookupF f = getCompose ∘∘ alterF (Compose ∘ liftA2 fmap (,) f) +-- | Map a function over each value in the map. mapWithKey :: StaticMap map => (Key map -> a -> b) -> map a -> map b mapWithKey f = runIdentity . traverseWithKey (Identity ∘∘ f) +-- | Map a function over each value in the map, gathering the 'Just' values and forgetting the 'Nothing'. mapMaybeWithKey :: Map map => (Key map -> a -> Maybe b) -> map a -> map b mapMaybeWithKey f = runIdentity . mapMaybeWithKeyA (pure ∘∘ f) +-- | Map a function over each value in the map, gathering the 'Left' and 'Right' separately. mapEitherWithKey :: Map map => (Key map -> a -> Either b c) -> map a -> (map b, map c) mapEitherWithKey f = runIdentity . mapEitherWithKeyA (pure ∘∘ f) @@ -193,60 +229,81 @@ fromListWithKeyM :: (Map map, Monad m) => (Key map -> a -> a -> m a) -> [(Key map, a)] -> m (map a) fromListWithKeyM f = sequenceA . fromListWithKey (bind2 . f) . (fmap . fmap) pure +-- | Modify the value of the key in the map, looking up the old value if the key is already present. If the key is absent, the map is returned unmodified. adjustLookupA :: (StaticMap map, Applicative p) => (a -> p a) -> Key map -> map a -> p (Maybe a, map a) adjustLookupA f = sequenceA ∘∘ (getLast *** id <<< getCompose) ∘∘ adjustA (\ a -> Compose (pure a, f a)) +-- | Map with a single element singleton :: Map map => Key map -> a -> map a singleton k a = fromList [(k, a)] +-- | Union of two maps, combining values of the same key with the given function unionWith :: Map map => (Key map -> a -> a -> a) -> map a -> map a -> map a unionWith f = runIdentity ∘∘ unionWithA (\ k -> pure ∘∘ f k) +-- | Intersection of two maps, combining values of the same key with the given function intersectionWith :: Map map => (Key map -> a -> b -> c) -> map a -> map b -> map c intersectionWith f = runIdentity ∘∘ intersectionWithA (\ k -> pure ∘∘ f k) +-- | Combine two maps with the given function, which is called once for each key present in either map, inclusive. merge :: Map map => (Key map -> Either' a b -> Maybe c) -> map a -> map b -> map c merge f = runIdentity ∘∘ mergeA (Identity ∘∘ f) +-- | Union of two maps, combining values of the same key with the given function unionWithA :: (Map map, Applicative p) => (Key map -> a -> a -> p a) -> map a -> map a -> p (map a) unionWithA f = mergeA (\ k -> \ case JustLeft a -> pure (Just a); JustRight a -> pure (Just a); Both a b -> Just <$> f k a b) +-- | Intersection of two maps, combining values of the same key with the given function intersectionWithA :: (Map map, Applicative p) => (Key map -> a -> b -> p c) -> map a -> map b -> p (map c) intersectionWithA f = mergeA (\ k -> \ case Both a b -> Just <$> f k a b; _ -> pure Nothing) +-- | Difference of two maps, which contains exactly the keys present in the first map but absent in the second difference :: Map map => map a -> map b -> map a difference = merge $ pure $ either' Just (pure Nothing) $ \ _ _ -> Nothing +-- | Symmetric difference of two maps, which contains exactly the keys present in the either map but absent in the other symmetricDifference :: Map map => map a -> map a -> map a symmetricDifference = merge $ pure $ either' Just Just $ \ _ _ -> Nothing +-- | Map a function over each key in the map. mapKeys :: (StaticMap m, Map n) => (Key m -> Key n) -> m a -> n a mapKeys f = foldrWithKey (insert . f) empty +-- | Map a function over each key in the map, combining values of keys which collide with the given function. mapKeysWith :: (StaticMap m, Map n) => (a -> a -> a) -> (Key m -> Key n) -> m a -> n a mapKeysWith combine f = foldrWithKey (insertWith combine . f) empty +-- | Traverse a function over each key in the map. traverseKeys :: (StaticMap m, Map n, Applicative p) => (Key m -> p (Key n)) -> m a -> p (n a) traverseKeys f = fmap (flip appEndo empty) . foldMapWithKeyA (\ i a -> (\ j -> Endo $ insert j a) <$> f i) +-- | Traverse a function over each key in the map, combining values of keys which collide with the given function. traverseKeysWith :: (StaticMap m, Map n, Applicative p) => (a -> a -> a) -> (Key m -> p (Key n)) -> m a -> p (n a) traverseKeysWith combine f = fmap (flip appEndo empty) . foldMapWithKeyA (\ i a -> (\ j -> Endo $ insertWith combine j a) <$> f i) +-- | Map a function over each key in the map, gathering the 'Just' values and forgetting the 'Nothing'. mapKeysMaybe :: (StaticMap m, Map n) => (Key m -> Maybe (Key n)) -> m a -> n a mapKeysMaybe f = runIdentity . traverseKeysMaybe (Identity . f) +-- | Map a function over each key in the map, gathering the 'Just' values and forgetting the 'Nothing', combining values of keys which collide with the given function. mapKeysMaybeWith :: (StaticMap m, Map n) => (a -> a -> a) -> (Key m -> Maybe (Key n)) -> m a -> n a mapKeysMaybeWith combine f = runIdentity . traverseKeysMaybeWith combine (Identity . f) +-- | Traverse a function over each key in the map, gathering the 'Just' values and forgetting the 'Nothing'. traverseKeysMaybe :: (StaticMap m, Map n, Applicative p) => (Key m -> p (Maybe (Key n))) -> m a -> p (n a) traverseKeysMaybe f = fmap (flip appEndo empty) . foldMapWithKeyA (\ i a -> foldMap (\ j -> Endo $ insert j a) <$> f i) +-- | Traverse a function over each key in the map, gathering the 'Just' values and forgetting the 'Nothing', combining values of keys which collide with the given function. traverseKeysMaybeWith :: (StaticMap m, Map n, Applicative p) => (a -> a -> a) -> (Key m -> p (Maybe (Key n))) -> m a -> p (n a) traverseKeysMaybeWith combine f = fmap (flip appEndo empty) . foldMapWithKeyA (\ i a -> foldMap (\ j -> Endo $ insertWith combine j a) <$> f i) +-- | Keys of the map+--+-- @'keys' as '!?' k = k '<$' (as '!?' k)@ keys :: StaticMap map => map a -> map (Key map) keys = mapWithKey pure +-- | Wrapper of a 'Map' whose semigroup operation is the union, combining values elementwise, and ergo whose monoidal unit is empty newtype Union map a = Union { unUnion :: map a }   deriving (Functor, Foldable, Traversable)   deriving (Eq, Ord, Read, Show) via map a@@ -272,6 +329,7 @@ instance (Map map, Semigroup a) => Monoid (Union map a) where     mempty = Union empty +-- | Wrapper of a 'Map' whose semigroup operation is the intersection, combining values elementwise newtype Intersection map a = Intersection { unIntersection :: map a }   deriving (Functor, Foldable, Traversable)   deriving (Eq, Ord, Read, Show) via map a@@ -294,6 +352,7 @@ instance (Map map, Semigroup a) => Semigroup (Intersection map a) where     (<>) = Intersection ∘∘ intersectionWith (pure (<>)) `on` unIntersection +-- | Wrapper of a 'Map' whose semigroup operation is the symmetric difference, and ergo whose monoidal unit is empty newtype SymmetricDifference map a = SymmetricDifference { unSymmetricDifference :: map a }   deriving (Functor, Foldable, Traversable)   deriving (Eq, Ord, Read, Show) via map a
Map.cabal view
@@ -1,5 +1,5 @@ name:                Map-version:             0.1.3.2+version:             0.1.3.3 synopsis:            Class of key-value maps -- description: license:             BSD3@@ -19,7 +19,7 @@   build-depends:       base >= 4.7 && < 5                      , containers >=0.5.9 && <0.7                      , either-both >=0.1.1 && <0.2-                     , filtrable >=0.1.2 && <0.2+                     , filtrable >=0.1.6 && <0.2                      , util >=0.1.14.1 && <0.2   default-language:    Haskell2010   default-extensions:  UnicodeSyntax