{-# LANGUAGE LambdaCase #-}
module Data.Map.Misc
(
diffMapNoEq
, diffMap
, applyMap
, mapPartitionEithers
, applyMapKeysSet
) where
import Data.Align
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import Data.These
diffMapNoEq :: (Ord k) => Map k v -> Map k v -> Map k (Maybe v)
diffMapNoEq :: forall k v. Ord k => Map k v -> Map k v -> Map k (Maybe v)
diffMapNoEq Map k v
olds Map k v
news = ((These v v -> Maybe (Maybe v))
-> Map k (These v v) -> Map k (Maybe v))
-> Map k (These v v)
-> (These v v -> Maybe (Maybe v))
-> Map k (Maybe v)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (These v v -> Maybe (Maybe v))
-> Map k (These v v) -> Map k (Maybe v)
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybe (Map k v -> Map k v -> Map k (These v v)
forall a b. Map k a -> Map k b -> Map k (These a b)
forall (f :: * -> *) a b.
Semialign f =>
f a -> f b -> f (These a b)
align Map k v
olds Map k v
news) ((These v v -> Maybe (Maybe v)) -> Map k (Maybe v))
-> (These v v -> Maybe (Maybe v)) -> Map k (Maybe v)
forall a b. (a -> b) -> a -> b
$ \case
This v
_ -> Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just Maybe v
forall a. Maybe a
Nothing
These v
_ v
new -> Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just (Maybe v -> Maybe (Maybe v)) -> Maybe v -> Maybe (Maybe v)
forall a b. (a -> b) -> a -> b
$ v -> Maybe v
forall a. a -> Maybe a
Just v
new
That v
new -> Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just (Maybe v -> Maybe (Maybe v)) -> Maybe v -> Maybe (Maybe v)
forall a b. (a -> b) -> a -> b
$ v -> Maybe v
forall a. a -> Maybe a
Just v
new
diffMap :: (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
diffMap :: forall k v. (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
diffMap Map k v
olds Map k v
news = ((These v v -> Maybe (Maybe v))
-> Map k (These v v) -> Map k (Maybe v))
-> Map k (These v v)
-> (These v v -> Maybe (Maybe v))
-> Map k (Maybe v)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (These v v -> Maybe (Maybe v))
-> Map k (These v v) -> Map k (Maybe v)
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybe (Map k v -> Map k v -> Map k (These v v)
forall a b. Map k a -> Map k b -> Map k (These a b)
forall (f :: * -> *) a b.
Semialign f =>
f a -> f b -> f (These a b)
align Map k v
olds Map k v
news) ((These v v -> Maybe (Maybe v)) -> Map k (Maybe v))
-> (These v v -> Maybe (Maybe v)) -> Map k (Maybe v)
forall a b. (a -> b) -> a -> b
$ \case
This v
_ -> Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just Maybe v
forall a. Maybe a
Nothing
These v
old v
new
| v
old v -> v -> Bool
forall a. Eq a => a -> a -> Bool
== v
new -> Maybe (Maybe v)
forall a. Maybe a
Nothing
| Bool
otherwise -> Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just (Maybe v -> Maybe (Maybe v)) -> Maybe v -> Maybe (Maybe v)
forall a b. (a -> b) -> a -> b
$ v -> Maybe v
forall a. a -> Maybe a
Just v
new
That v
new -> Maybe v -> Maybe (Maybe v)
forall a. a -> Maybe a
Just (Maybe v -> Maybe (Maybe v)) -> Maybe v -> Maybe (Maybe v)
forall a b. (a -> b) -> a -> b
$ v -> Maybe v
forall a. a -> Maybe a
Just v
new
applyMap :: Ord k => Map k (Maybe v) -> Map k v -> Map k v
applyMap :: forall k v. Ord k => Map k (Maybe v) -> Map k v -> Map k v
applyMap Map k (Maybe v)
patch Map k v
old = Map k v
insertions Map k v -> Map k v -> Map k v
forall k a. Ord k => Map k a -> Map k a -> Map k a
`Map.union` (Map k v
old Map k v -> Map k () -> Map k v
forall k a b. Ord k => Map k a -> Map k b -> Map k a
`Map.difference` Map k ()
deletions)
where (Map k ()
deletions, Map k v
insertions) = (Maybe v -> Either () v) -> Map k (Maybe v) -> (Map k (), Map k v)
forall a b c k. (a -> Either b c) -> Map k a -> (Map k b, Map k c)
Map.mapEither Maybe v -> Either () v
forall {b}. Maybe b -> Either () b
maybeToEither Map k (Maybe v)
patch
maybeToEither :: Maybe b -> Either () b
maybeToEither = \case
Maybe b
Nothing -> () -> Either () b
forall a b. a -> Either a b
Left ()
Just b
r -> b -> Either () b
forall a b. b -> Either a b
Right b
r
{-# DEPRECATED mapPartitionEithers "Use 'mapEither' instead" #-}
mapPartitionEithers :: Map k (Either a b) -> (Map k a, Map k b)
mapPartitionEithers :: forall k a b. Map k (Either a b) -> (Map k a, Map k b)
mapPartitionEithers = (Either a b -> Either a b)
-> Map k (Either a b) -> (Map k a, Map k b)
forall a b c k. (a -> Either b c) -> Map k a -> (Map k b, Map k c)
Map.mapEither Either a b -> Either a b
forall a. a -> a
id
applyMapKeysSet :: Ord k => Map k (Maybe v) -> Set k -> Set k
applyMapKeysSet :: forall k v. Ord k => Map k (Maybe v) -> Set k -> Set k
applyMapKeysSet Map k (Maybe v)
patch Set k
old = Map k (Maybe v) -> Set k
forall k a. Map k a -> Set k
Map.keysSet Map k (Maybe v)
insertions Set k -> Set k -> Set k
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` (Set k
old Set k -> Set k -> Set k
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` Map k (Maybe v) -> Set k
forall k a. Map k a -> Set k
Map.keysSet Map k (Maybe v)
deletions)
where (Map k (Maybe v)
insertions, Map k (Maybe v)
deletions) = (Maybe v -> Bool)
-> Map k (Maybe v) -> (Map k (Maybe v), Map k (Maybe v))
forall a k. (a -> Bool) -> Map k a -> (Map k a, Map k a)
Map.partition Maybe v -> Bool
forall a. Maybe a -> Bool
isJust Map k (Maybe v)
patch