{-# language BangPatterns        #-}
{-# language DeriveGeneric       #-}
{-# language DeriveFoldable      #-}
{-# language DeriveFunctor       #-}
{-# language DeriveTraversable   #-}
{-# language NoImplicitPrelude   #-}
{-# language ScopedTypeVariables #-}

-- | This module provides a lossless way to do
--   diffing between two 'Map's, and ways to
--   manipulate the diffs.
module Patience.Map
  ( -- * Types 
    Delta(..)
  , M(..)

    -- * Diffing 
  , diff

    -- * Case analysis on 'Delta'
  , getSame
  , getOld
  , getNew
  , getDelta
  , getOriginal
  , getOriginals

  , isSame
  , isOld
  , isNew
  , isDelta

    -- * Construction of special maps from a diff
  , toSame 
  , toOld
  , toNew
  , toDelta
  , toOriginal
  , toOriginals 

    -- * Mapping
  , mapSame
  , mapOld
  , mapNew

  , mapSame'
  , mapOld'
  , mapNew'
  ) where

import           Data.Bool             (Bool(True, False))
import           Data.Eq               (Eq((==)))
import           Data.Foldable         (Foldable)
import           Data.Function         ((.))
import           Data.Functor          (Functor(fmap))
import           Data.Maybe            (Maybe(Just,Nothing))
import           Data.Ord              (Ord)
import           Data.Traversable      (Traversable)
import           GHC.Generics          (Generic, Generic1)
import           GHC.Show              (Show)
import           Data.Map.Strict       (Map)
import qualified Data.Map.Strict       as DMS
import qualified Data.Map.Merge.Strict as Merge

-- | The result of a diff of an entry within two 'Map's.
--
--   In two 'Map's m1 and m2, when performing a diff, this type encodes the following situations:
--
--   Same key, different values: Stores the two values in the Delta constructor.
--
--   Same key, same values: Stores the value in the Same constructor.
--
--   Key exists in m1 but not m2: Stores the value in the Old constructor.
--
--   Key exists in m2 but not m1: Stores the value in the New constructor.
--
--   This behaviour ensures that we don't lose any information, meaning
--   we can reconstruct either of the original 'Map' 'k' 'a' from a 'Map' 'k' ('Delta' 'a').
--   (Note that this slightly differs from `Patience.diff`, which does not
--   care about the possibility of reconstruction).
data Delta a
  = Delta !a !a
  | Same !a
  | Old  !a
  | New  !a
  deriving (Delta a -> Delta a -> Bool
(Delta a -> Delta a -> Bool)
-> (Delta a -> Delta a -> Bool) -> Eq (Delta a)
forall a. Eq a => Delta a -> Delta a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Delta a -> Delta a -> Bool
$c/= :: forall a. Eq a => Delta a -> Delta a -> Bool
== :: Delta a -> Delta a -> Bool
$c== :: forall a. Eq a => Delta a -> Delta a -> Bool
Eq, Delta a -> Bool
(a -> m) -> Delta a -> m
(a -> b -> b) -> b -> Delta a -> b
(forall m. Monoid m => Delta m -> m)
-> (forall m a. Monoid m => (a -> m) -> Delta a -> m)
-> (forall m a. Monoid m => (a -> m) -> Delta a -> m)
-> (forall a b. (a -> b -> b) -> b -> Delta a -> b)
-> (forall a b. (a -> b -> b) -> b -> Delta a -> b)
-> (forall b a. (b -> a -> b) -> b -> Delta a -> b)
-> (forall b a. (b -> a -> b) -> b -> Delta a -> b)
-> (forall a. (a -> a -> a) -> Delta a -> a)
-> (forall a. (a -> a -> a) -> Delta a -> a)
-> (forall a. Delta a -> [a])
-> (forall a. Delta a -> Bool)
-> (forall a. Delta a -> Int)
-> (forall a. Eq a => a -> Delta a -> Bool)
-> (forall a. Ord a => Delta a -> a)
-> (forall a. Ord a => Delta a -> a)
-> (forall a. Num a => Delta a -> a)
-> (forall a. Num a => Delta a -> a)
-> Foldable Delta
forall a. Eq a => a -> Delta a -> Bool
forall a. Num a => Delta a -> a
forall a. Ord a => Delta a -> a
forall m. Monoid m => Delta m -> m
forall a. Delta a -> Bool
forall a. Delta a -> Int
forall a. Delta a -> [a]
forall a. (a -> a -> a) -> Delta a -> a
forall m a. Monoid m => (a -> m) -> Delta a -> m
forall b a. (b -> a -> b) -> b -> Delta a -> b
forall a b. (a -> b -> b) -> b -> Delta a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Delta a -> a
$cproduct :: forall a. Num a => Delta a -> a
sum :: Delta a -> a
$csum :: forall a. Num a => Delta a -> a
minimum :: Delta a -> a
$cminimum :: forall a. Ord a => Delta a -> a
maximum :: Delta a -> a
$cmaximum :: forall a. Ord a => Delta a -> a
elem :: a -> Delta a -> Bool
$celem :: forall a. Eq a => a -> Delta a -> Bool
length :: Delta a -> Int
$clength :: forall a. Delta a -> Int
null :: Delta a -> Bool
$cnull :: forall a. Delta a -> Bool
toList :: Delta a -> [a]
$ctoList :: forall a. Delta a -> [a]
foldl1 :: (a -> a -> a) -> Delta a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Delta a -> a
foldr1 :: (a -> a -> a) -> Delta a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Delta a -> a
foldl' :: (b -> a -> b) -> b -> Delta a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Delta a -> b
foldl :: (b -> a -> b) -> b -> Delta a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Delta a -> b
foldr' :: (a -> b -> b) -> b -> Delta a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Delta a -> b
foldr :: (a -> b -> b) -> b -> Delta a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Delta a -> b
foldMap' :: (a -> m) -> Delta a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Delta a -> m
foldMap :: (a -> m) -> Delta a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Delta a -> m
fold :: Delta m -> m
$cfold :: forall m. Monoid m => Delta m -> m
Foldable, a -> Delta b -> Delta a
(a -> b) -> Delta a -> Delta b
(forall a b. (a -> b) -> Delta a -> Delta b)
-> (forall a b. a -> Delta b -> Delta a) -> Functor Delta
forall a b. a -> Delta b -> Delta a
forall a b. (a -> b) -> Delta a -> Delta b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Delta b -> Delta a
$c<$ :: forall a b. a -> Delta b -> Delta a
fmap :: (a -> b) -> Delta a -> Delta b
$cfmap :: forall a b. (a -> b) -> Delta a -> Delta b
Functor, (forall x. Delta a -> Rep (Delta a) x)
-> (forall x. Rep (Delta a) x -> Delta a) -> Generic (Delta a)
forall x. Rep (Delta a) x -> Delta a
forall x. Delta a -> Rep (Delta a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Delta a) x -> Delta a
forall a x. Delta a -> Rep (Delta a) x
$cto :: forall a x. Rep (Delta a) x -> Delta a
$cfrom :: forall a x. Delta a -> Rep (Delta a) x
Generic, (forall a. Delta a -> Rep1 Delta a)
-> (forall a. Rep1 Delta a -> Delta a) -> Generic1 Delta
forall a. Rep1 Delta a -> Delta a
forall a. Delta a -> Rep1 Delta a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cto1 :: forall a. Rep1 Delta a -> Delta a
$cfrom1 :: forall a. Delta a -> Rep1 Delta a
Generic1, Eq (Delta a)
Eq (Delta a) =>
(Delta a -> Delta a -> Ordering)
-> (Delta a -> Delta a -> Bool)
-> (Delta a -> Delta a -> Bool)
-> (Delta a -> Delta a -> Bool)
-> (Delta a -> Delta a -> Bool)
-> (Delta a -> Delta a -> Delta a)
-> (Delta a -> Delta a -> Delta a)
-> Ord (Delta a)
Delta a -> Delta a -> Bool
Delta a -> Delta a -> Ordering
Delta a -> Delta a -> Delta a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Delta a)
forall a. Ord a => Delta a -> Delta a -> Bool
forall a. Ord a => Delta a -> Delta a -> Ordering
forall a. Ord a => Delta a -> Delta a -> Delta a
min :: Delta a -> Delta a -> Delta a
$cmin :: forall a. Ord a => Delta a -> Delta a -> Delta a
max :: Delta a -> Delta a -> Delta a
$cmax :: forall a. Ord a => Delta a -> Delta a -> Delta a
>= :: Delta a -> Delta a -> Bool
$c>= :: forall a. Ord a => Delta a -> Delta a -> Bool
> :: Delta a -> Delta a -> Bool
$c> :: forall a. Ord a => Delta a -> Delta a -> Bool
<= :: Delta a -> Delta a -> Bool
$c<= :: forall a. Ord a => Delta a -> Delta a -> Bool
< :: Delta a -> Delta a -> Bool
$c< :: forall a. Ord a => Delta a -> Delta a -> Bool
compare :: Delta a -> Delta a -> Ordering
$ccompare :: forall a. Ord a => Delta a -> Delta a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Delta a)
Ord, Int -> Delta a -> ShowS
[Delta a] -> ShowS
Delta a -> String
(Int -> Delta a -> ShowS)
-> (Delta a -> String) -> ([Delta a] -> ShowS) -> Show (Delta a)
forall a. Show a => Int -> Delta a -> ShowS
forall a. Show a => [Delta a] -> ShowS
forall a. Show a => Delta a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Delta a] -> ShowS
$cshowList :: forall a. Show a => [Delta a] -> ShowS
show :: Delta a -> String
$cshow :: forall a. Show a => Delta a -> String
showsPrec :: Int -> Delta a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Delta a -> ShowS
Show, Functor Delta
Foldable Delta
(Functor Delta, Foldable Delta) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Delta a -> f (Delta b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Delta (f a) -> f (Delta a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Delta a -> m (Delta b))
-> (forall (m :: * -> *) a. Monad m => Delta (m a) -> m (Delta a))
-> Traversable Delta
(a -> f b) -> Delta a -> f (Delta b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Delta (m a) -> m (Delta a)
forall (f :: * -> *) a. Applicative f => Delta (f a) -> f (Delta a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Delta a -> m (Delta b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Delta a -> f (Delta b)
sequence :: Delta (m a) -> m (Delta a)
$csequence :: forall (m :: * -> *) a. Monad m => Delta (m a) -> m (Delta a)
mapM :: (a -> m b) -> Delta a -> m (Delta b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Delta a -> m (Delta b)
sequenceA :: Delta (f a) -> f (Delta a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Delta (f a) -> f (Delta a)
traverse :: (a -> f b) -> Delta a -> f (Delta b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Delta a -> f (Delta b)
$cp2Traversable :: Foldable Delta
$cp1Traversable :: Functor Delta
Traversable)

-- | M1 = First 'Map', M2 = Second 'Map'.
--   Used as an argument for functions that care about which 'Map' to reconstruct.
data M = M1 | M2

-- | Takes two 'Map's and returns a 'Map' from the same key type to 'Delta' 'a',
--   where 'Delta' 'a' encodes differences between entries.
diff :: (Eq a, Ord k)
     => Map k a -- ^ first, /old/ 'Map'
     -> Map k a -- ^ second, /new/ 'Map'
     -> Map k (Delta a) -- ^ 'Map' encoding the diff
diff :: Map k a -> Map k a -> Map k (Delta a)
diff !Map k a
m1 !Map k a
m2 =
  SimpleWhenMissing k a (Delta a)
-> SimpleWhenMissing k a (Delta a)
-> SimpleWhenMatched k a a (Delta a)
-> Map k a
-> Map k a
-> Map k (Delta a)
forall k a c b.
Ord k =>
SimpleWhenMissing k a c
-> SimpleWhenMissing k b c
-> SimpleWhenMatched k a b c
-> Map k a
-> Map k b
-> Map k c
Merge.merge
    ((k -> a -> Delta a) -> SimpleWhenMissing k a (Delta a)
forall (f :: * -> *) k x y.
Applicative f =>
(k -> x -> y) -> WhenMissing f k x y
Merge.mapMissing (\_ x :: a
x -> a -> Delta a
forall a. a -> Delta a
Old a
x)) -- preserve keys found in m1 but not m2
    ((k -> a -> Delta a) -> SimpleWhenMissing k a (Delta a)
forall (f :: * -> *) k x y.
Applicative f =>
(k -> x -> y) -> WhenMissing f k x y
Merge.mapMissing (\_ x :: a
x -> a -> Delta a
forall a. a -> Delta a
New a
x)) -- preserve keys found in m2 but not m1
    ((k -> a -> a -> Delta a) -> SimpleWhenMatched k a a (Delta a)
forall (f :: * -> *) k x y z.
Applicative f =>
(k -> x -> y -> z) -> WhenMatched f k x y z
Merge.zipWithMatched (\_ v1 :: a
v1 v2 :: a
v2 -> if a
v1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
v2 then a -> Delta a
forall a. a -> Delta a
Same a
v1 else a -> a -> Delta a
forall a. a -> a -> Delta a
Delta a
v1 a
v2))
    Map k a
m1
    Map k a
m2
{-# INLINABLE diff #-}

-- | Is the 'Delta' an encoding of same values?
isSame :: Eq a => Delta a -> Bool
isSame :: Delta a -> Bool
isSame (Same    _) = Bool
True
isSame (Delta x :: a
x y :: a
y) =
  if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y
  then Bool
True
  else Bool
False
isSame                      _  = Bool
False
{-# INLINABLE isSame #-}

-- | Is the 'Delta' an encoding of old values?
isOld :: Delta a -> Bool
isOld :: Delta a -> Bool
isOld (Old     _) = Bool
True
isOld (Delta _ _) = Bool
True
isOld                     _   = Bool
False
{-# INLINE isOld #-}

-- | Is the 'Delta' an encoding of new values?
isNew :: Delta a -> Bool
isNew :: Delta a -> Bool
isNew (New     _) = Bool
True
isNew (Delta _ _) = Bool
True
isNew           _ = Bool
False
{-# INLINE isNew #-}

-- | Is the 'Delta' an encoding of changed values?
isDelta :: Delta a -> Bool
isDelta :: Delta a -> Bool
isDelta (Delta _ _) = Bool
True
isDelta        _    = Bool
False
{-# INLINE isDelta #-}

-- | Potentially get the 'Same' value out of a 'Delta'.
getSame :: Eq a => Delta a -> Maybe a
getSame :: Delta a -> Maybe a
getSame (Same a :: a
a)    = a -> Maybe a
forall a. a -> Maybe a
Just a
a
getSame (Delta x :: a
x y :: a
y) =
  if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y
  then a -> Maybe a
forall a. a -> Maybe a
Just a
x
  else Maybe a
forall a. Maybe a
Nothing
getSame _        = Maybe a
forall a. Maybe a
Nothing
{-# INLINABLE getSame #-}

-- | Potentially get the 'Old' value out of a 'Delta'.
getOld :: Delta a -> Maybe a
getOld :: Delta a -> Maybe a
getOld (Delta a :: a
a _) = a -> Maybe a
forall a. a -> Maybe a
Just a
a
getOld (Old a :: a
a)     = a -> Maybe a
forall a. a -> Maybe a
Just a
a
getOld _           = Maybe a
forall a. Maybe a
Nothing
{-# INLINE getOld #-}

-- | Potentially get the 'New' value out of a 'Delta'.
getNew :: Delta a -> Maybe a
getNew :: Delta a -> Maybe a
getNew (Delta _ a :: a
a) = a -> Maybe a
forall a. a -> Maybe a
Just a
a
getNew (New a :: a
a)     = a -> Maybe a
forall a. a -> Maybe a
Just a
a
getNew _           = Maybe a
forall a. Maybe a
Nothing
{-# INLINE getNew #-}

-- | Potentially get the 'Changed' value out of a 'Delta'.
getDelta :: Delta a -> Maybe (a,a)
getDelta :: Delta a -> Maybe (a, a)
getDelta (Delta d1 :: a
d1 d2 :: a
d2) = (a, a) -> Maybe (a, a)
forall a. a -> Maybe a
Just (a
d1,a
d2)
getDelta _             = Maybe (a, a)
forall a. Maybe a
Nothing
{-# INLINE getDelta #-}  

-- | Potentially get the original value out of the 'Delta'.
getOriginal :: M -> Delta a -> Maybe a
getOriginal :: M -> Delta a -> Maybe a
getOriginal M1 (Delta x :: a
x _) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
getOriginal M2 (Delta _ y :: a
y) = a -> Maybe a
forall a. a -> Maybe a
Just a
y
getOriginal _  (Same  x :: a
x  ) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
getOriginal M1 (Old   x :: a
x  ) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
getOriginal _  (Old   _  ) = Maybe a
forall a. Maybe a
Nothing
getOriginal M2 (New   x :: a
x  ) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
getOriginal _  (New   _  ) = Maybe a
forall a. Maybe a
Nothing
{-# INLINE getOriginal #-}

-- | Get the original values out of the 'Delta'.
getOriginals :: Delta a -> (Maybe a, Maybe a)
getOriginals :: Delta a -> (Maybe a, Maybe a)
getOriginals (Delta x :: a
x y :: a
y) = (a -> Maybe a
forall a. a -> Maybe a
Just a
x, a -> Maybe a
forall a. a -> Maybe a
Just a
y)
getOriginals (Same  x :: a
x  ) = (a -> Maybe a
forall a. a -> Maybe a
Just a
x, a -> Maybe a
forall a. a -> Maybe a
Just a
x)
getOriginals (Old   x :: a
x  ) = (a -> Maybe a
forall a. a -> Maybe a
Just a
x, Maybe a
forall a. Maybe a
Nothing)
getOriginals (New   x :: a
x  ) = (Maybe a
forall a. Maybe a
Nothing, a -> Maybe a
forall a. a -> Maybe a
Just a
x)
{-# INLINE getOriginals #-}

-- | Retrieve the 'Same' values out of the diff map.
toSame :: Eq a => Map k (Delta a)
       -> Map k a
toSame :: Map k (Delta a) -> Map k a
toSame = (Delta a -> Maybe a) -> Map k (Delta a) -> Map k a
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe Delta a -> Maybe a
forall a. Eq a => Delta a -> Maybe a
getSame
{-# INLINABLE toSame #-}

-- | Retrieve only the 'Old' values out of the diff map.
toOld :: Map k (Delta a)
      -> Map k a
toOld :: Map k (Delta a) -> Map k a
toOld = (Delta a -> Maybe a) -> Map k (Delta a) -> Map k a
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe Delta a -> Maybe a
forall a. Delta a -> Maybe a
getOld
{-# INLINE toOld #-}

-- | Retrieve only the 'New' values out of the diff map.
toNew :: Map k (Delta a)
      -> Map k a
toNew :: Map k (Delta a) -> Map k a
toNew = (Delta a -> Maybe a) -> Map k (Delta a) -> Map k a
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe Delta a -> Maybe a
forall a. Delta a -> Maybe a
getNew
{-# INLINE toNew #-}

-- | Retrieve only the 'DeltaUnit' values out of the diff map.
toDelta :: Map k (Delta a)
        -> Map k (a,a)
toDelta :: Map k (Delta a) -> Map k (a, a)
toDelta = (Delta a -> Maybe (a, a)) -> Map k (Delta a) -> Map k (a, a)
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe Delta a -> Maybe (a, a)
forall a. Delta a -> Maybe (a, a)
getDelta
{-# INLINE toDelta #-}

-- | Construct either the old 'Map' or new 'Map' from a diff
toOriginal :: M
           -> Map k (Delta a)
           -> Map k a
toOriginal :: M -> Map k (Delta a) -> Map k a
toOriginal m :: M
m = (Delta a -> Maybe a) -> Map k (Delta a) -> Map k a
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe (M -> Delta a -> Maybe a
forall a. M -> Delta a -> Maybe a
getOriginal M
m)
{-# INLINE toOriginal #-}

-- | Reconstruct both original 'Map's.
toOriginals :: Map k (Delta a)
            -> (Map k a, Map k a)
toOriginals :: Map k (Delta a) -> (Map k a, Map k a)
toOriginals m :: Map k (Delta a)
m = ((Delta a -> Maybe a) -> Map k (Delta a) -> Map k a
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe (M -> Delta a -> Maybe a
forall a. M -> Delta a -> Maybe a
getOriginal M
M1) Map k (Delta a)
m, (Delta a -> Maybe a) -> Map k (Delta a) -> Map k a
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe (M -> Delta a -> Maybe a
forall a. M -> Delta a -> Maybe a
getOriginal M
M2) Map k (Delta a)
m)

-- | Map over all 'Same' values, returning a map of just
--   the transformed values.
--   This can be more efficient than calling 'toSame' and
--   then Data.Map's 'DMS.map'.
mapSame :: Eq a
        => (a -> b)
        -> Map k (Delta a)
        -> Map k b
mapSame :: (a -> b) -> Map k (Delta a) -> Map k b
mapSame f :: a -> b
f = (Delta a -> Maybe b) -> Map k (Delta a) -> Map k b
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe ((a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Maybe a -> Maybe b) -> (Delta a -> Maybe a) -> Delta a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Delta a -> Maybe a
forall a. Eq a => Delta a -> Maybe a
getSame)
{-# INLINABLE mapSame #-}

-- | Map over all 'Old' values, returning a map of just
--   the transformed values.
--   This can be more efficient than calling 'toOld' and
--   then Data.Map's 'DMS.map'.
mapOld :: (a -> b)
       -> Map k (Delta a)
       -> Map k b
mapOld :: (a -> b) -> Map k (Delta a) -> Map k b
mapOld f :: a -> b
f = (Delta a -> Maybe b) -> Map k (Delta a) -> Map k b
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe ((a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Maybe a -> Maybe b) -> (Delta a -> Maybe a) -> Delta a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Delta a -> Maybe a
forall a. Delta a -> Maybe a
getOld)
{-# INLINE mapOld #-}

-- | Map over all 'New' values, returning a map of just
--   the transformed values.
--   This can be more efficient than calling 'toNew' and
--   then Data.Map's 'DMS.map'.
mapNew :: (a -> b)
       -> Map k (Delta a)
       -> Map k b
mapNew :: (a -> b) -> Map k (Delta a) -> Map k b
mapNew f :: a -> b
f = (Delta a -> Maybe b) -> Map k (Delta a) -> Map k b
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
DMS.mapMaybe ((a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Maybe a -> Maybe b) -> (Delta a -> Maybe a) -> Delta a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Delta a -> Maybe a
forall a. Delta a -> Maybe a
getNew)
{-# INLINE mapNew #-}

-- | Map over all the 'Same' values, preserving the
--   remaining values in the map.
mapSame' :: Eq a
         => (a -> a)
         -> Map k (Delta a)
         -> Map k (Delta a)
mapSame' :: (a -> a) -> Map k (Delta a) -> Map k (Delta a)
mapSame' f :: a -> a
f = (Delta a -> Delta a) -> Map k (Delta a) -> Map k (Delta a)
forall a b k. (a -> b) -> Map k a -> Map k b
DMS.map (\x :: Delta a
x -> if Delta a -> Bool
forall a. Eq a => Delta a -> Bool
isSame Delta a
x then (a -> a) -> Delta a -> Delta a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
f Delta a
x else Delta a
x)
{-# INLINABLE mapSame' #-}

-- | Map over all the 'Old' values, preserving the
--   remaining values in the map.
mapOld' :: (a -> a)
        -> Map k (Delta a)
        -> Map k (Delta a)
mapOld' :: (a -> a) -> Map k (Delta a) -> Map k (Delta a)
mapOld' f :: a -> a
f = (Delta a -> Delta a) -> Map k (Delta a) -> Map k (Delta a)
forall a b k. (a -> b) -> Map k a -> Map k b
DMS.map Delta a -> Delta a
go
  where
    go :: Delta a -> Delta a
go (Old x :: a
x) = a -> Delta a
forall a. a -> Delta a
Old (a -> a
f a
x)
    go (Delta x :: a
x y :: a
y) = a -> a -> Delta a
forall a. a -> a -> Delta a
Delta (a -> a
f a
x) a
y
    go x :: Delta a
x = Delta a
x
{-# INLINE mapOld' #-}

-- | Map over all the 'New' values, preserving the
--   remaining values in the map.
mapNew' :: (a -> a)
        -> Map k (Delta a)
        -> Map k (Delta a)
mapNew' :: (a -> a) -> Map k (Delta a) -> Map k (Delta a)
mapNew' f :: a -> a
f = (Delta a -> Delta a) -> Map k (Delta a) -> Map k (Delta a)
forall a b k. (a -> b) -> Map k a -> Map k b
DMS.map Delta a -> Delta a
go
  where
    go :: Delta a -> Delta a
go (New x :: a
x) = a -> Delta a
forall a. a -> Delta a
New (a -> a
f a
x)
    go (Delta x :: a
x y :: a
y) = a -> a -> Delta a
forall a. a -> a -> Delta a
Delta a
x (a -> a
f a
y)
    go x :: Delta a
x = Delta a
x
{-# INLINE mapNew' #-}