    {-# 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(..)

        -- * Diffing
      , diff

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

      , isSame
      , isOld
      , isNew
      , isDelta

        -- * Construction of special maps from a diff
      , toSame
      , toOld
      , toNew
      , toDelta
      , 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.Tuple            (fst,snd)
    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
    $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
    /= :: Delta a -> Delta a -> Bool
    Eq, (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
    $cfold :: forall m. Monoid m => Delta m -> m
    fold :: forall m. Monoid m => Delta m -> m
    $cfoldMap :: forall m a. Monoid m => (a -> m) -> Delta a -> m
    foldMap :: forall m a. Monoid m => (a -> m) -> Delta a -> m
    $cfoldMap' :: forall m a. Monoid m => (a -> m) -> Delta a -> m
    foldMap' :: forall m a. Monoid m => (a -> m) -> Delta a -> m
    $cfoldr :: forall a b. (a -> b -> b) -> b -> Delta a -> b
    foldr :: forall a b. (a -> b -> b) -> b -> Delta a -> b
    $cfoldr' :: forall a b. (a -> b -> b) -> b -> Delta a -> b
    foldr' :: forall a b. (a -> b -> b) -> b -> Delta a -> b
    $cfoldl :: forall b a. (b -> a -> b) -> b -> Delta a -> b
    foldl :: forall b a. (b -> a -> b) -> b -> Delta a -> b
    $cfoldl' :: forall b a. (b -> a -> b) -> b -> Delta a -> b
    foldl' :: forall b a. (b -> a -> b) -> b -> Delta a -> b
    $cfoldr1 :: forall a. (a -> a -> a) -> Delta a -> a
    foldr1 :: forall a. (a -> a -> a) -> Delta a -> a
    $cfoldl1 :: forall a. (a -> a -> a) -> Delta a -> a
    foldl1 :: forall a. (a -> a -> a) -> Delta a -> a
    $ctoList :: forall a. Delta a -> [a]
    toList :: forall a. Delta a -> [a]
    $cnull :: forall a. Delta a -> Bool
    null :: forall a. Delta a -> Bool
    $clength :: forall a. Delta a -> Int
    length :: forall a. Delta a -> Int
    $celem :: forall a. Eq a => a -> Delta a -> Bool
    elem :: forall a. Eq a => a -> Delta a -> Bool
    $cmaximum :: forall a. Ord a => Delta a -> a
    maximum :: forall a. Ord a => Delta a -> a
    $cminimum :: forall a. Ord a => Delta a -> a
    minimum :: forall a. Ord a => Delta a -> a
    $csum :: forall a. Num a => Delta a -> a
    sum :: forall a. Num a => Delta a -> a
    $cproduct :: forall a. Num a => Delta a -> a
    product :: forall a. Num a => Delta a -> a
    Foldable, (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
    $cfmap :: forall a b. (a -> b) -> Delta a -> Delta b
    fmap :: forall a b. (a -> b) -> Delta a -> Delta b
    $c<$ :: forall a b. a -> Delta b -> Delta a
    <$ :: forall a b. a -> Delta b -> Delta a
    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
    $cfrom :: forall a x. Delta a -> Rep (Delta a) x
    from :: forall x. Delta a -> Rep (Delta a) x
    $cto :: forall a x. Rep (Delta a) x -> Delta a
    to :: forall x. Rep (Delta a) x -> Delta a
    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
    $cfrom1 :: forall a. Delta a -> Rep1 Delta a
    from1 :: forall a. Delta a -> Rep1 Delta a
    $cto1 :: forall a. Rep1 Delta a -> Delta a
    to1 :: forall a. Rep1 Delta a -> 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
    $ccompare :: forall a. Ord a => Delta a -> Delta a -> Ordering
    compare :: Delta a -> Delta a -> Ordering
    $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
    >= :: Delta a -> Delta a -> Bool
    $cmax :: forall a. Ord a => Delta a -> Delta a -> Delta a
    max :: Delta a -> Delta a -> Delta a
    $cmin :: forall a. Ord a => Delta a -> Delta a -> Delta a
    min :: Delta a -> Delta a -> 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
    $cshowsPrec :: forall a. Show a => Int -> Delta a -> ShowS
    showsPrec :: Int -> Delta a -> ShowS
    $cshow :: forall a. Show a => Delta a -> String
    show :: Delta a -> String
    $cshowList :: forall a. Show a => [Delta a] -> ShowS
    showList :: [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
    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)
    $ctraverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Delta a -> f (Delta b)
    traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Delta a -> f (Delta b)
    $csequenceA :: forall (f :: * -> *) a. Applicative f => Delta (f a) -> f (Delta a)
    sequenceA :: forall (f :: * -> *) a. Applicative f => Delta (f a) -> f (Delta a)
    $cmapM :: forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Delta a -> m (Delta b)
    mapM :: forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Delta a -> m (Delta b)
    $csequence :: forall (m :: * -> *) a. Monad m => Delta (m a) -> m (Delta a)
    sequence :: forall (m :: * -> *) a. Monad m => Delta (m a) -> m (Delta a)
    Traversable)

    -- | 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 :: forall a k. (Eq a, Ord k) => 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 (\k
    _ 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 (\k
    _ 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 (\k
    _ a
    v1 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 :: forall a. Eq a => Delta a -> Bool
    isSame (Same    a
    _) = Bool
    True
    isSame (Delta a
    x a
    y) = a
    x a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    y
    isSame          Delta a
    _  = Bool
    False
    {-# INLINABLE isSame #-}

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

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

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

    -- | Potentially get the 'Same' value out of a 'Delta'.
    getSame :: Eq a => Delta a -> Maybe a
    getSame :: forall a. Eq a => Delta a -> Maybe a
    getSame (Same a
    a)    = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a
    getSame (Delta a
    x 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           Delta a
    _ = Maybe a
    forall a. Maybe a
    Nothing
    {-# INLINABLE getSame #-}

    -- | Potentially get the 'Old' value out of a 'Delta'.
    getOld :: Delta a -> Maybe a
    getOld :: forall a. 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 -> Maybe a
    forall a. a -> Maybe a
    Just a
    a
    getOld           Delta a
    _ = Maybe a
    forall a. Maybe a
    Nothing
    {-# INLINE getOld #-}

    -- | Potentially get the 'New' value out of a 'Delta'.
    getNew :: Delta a -> Maybe a
    getNew :: forall a. 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 -> Maybe a
    forall a. a -> Maybe a
    Just a
    a
    getNew           Delta a
    _ = 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 :: forall a. Delta a -> Maybe (a, a)
    getDelta (Delta a
    d1 a
    d2) = (a, a) -> Maybe (a, a)
    forall a. a -> Maybe a
    Just (a
    d1,a
    d2)
    getDelta             Delta a
    _ = Maybe (a, a)
    forall a. Maybe a
    Nothing
    {-# INLINE getDelta #-}

    -- | Get the original values out of the 'Delta'.
    getOriginals :: Delta a -> (Maybe a, Maybe a)
    getOriginals :: forall a. Delta a -> (Maybe a, Maybe a)
    getOriginals (Delta a
    x 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  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   a
    x  ) = (a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x, Maybe a
    forall a. Maybe a
    Nothing)
    getOriginals (New   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 :: forall a k. Eq a => 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 :: forall k a. 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 :: forall k a. 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 :: forall k a. 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 #-}

    -- | Reconstruct both original 'Map's.
    toOriginals :: Map k (Delta a)
                -> (Map k a, Map k a)
    toOriginals :: forall k a. Map k (Delta a) -> (Map k a, Map k a)
    toOriginals 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 ((Maybe a, Maybe a) -> Maybe a
    forall a b. (a, b) -> a
    fst ((Maybe a, Maybe a) -> Maybe a)
    -> (Delta a -> (Maybe a, Maybe a)) -> Delta a -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Delta a -> (Maybe a, Maybe a)
    forall a. Delta a -> (Maybe a, Maybe a)
    getOriginals) 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 ((Maybe a, Maybe a) -> Maybe a
    forall a b. (a, b) -> b
    snd ((Maybe a, Maybe a) -> Maybe a)
    -> (Delta a -> (Maybe a, Maybe a)) -> Delta a -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Delta a -> (Maybe a, Maybe a)
    forall a. Delta a -> (Maybe a, Maybe a)
    getOriginals) 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 :: forall a b k. Eq a => (a -> b) -> Map k (Delta a) -> Map k b
    mapSame 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 a b. (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 :: forall a b k. (a -> b) -> Map k (Delta a) -> Map k b
    mapOld 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 a b. (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 :: forall a b k. (a -> b) -> Map k (Delta a) -> Map k b
    mapNew 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 a b. (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' :: forall a k. Eq a => (a -> a) -> Map k (Delta a) -> Map k (Delta a)
    mapSame' 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
    x -> if Delta a -> Bool
    forall a. Eq a => Delta a -> Bool
    isSame Delta a
    x then (a -> a) -> Delta a -> Delta a
    forall a b. (a -> b) -> Delta a -> Delta b
    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' :: forall a k. (a -> a) -> Map k (Delta a) -> Map k (Delta a)
    mapOld' 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 a
    x) = a -> Delta a
    forall a. a -> Delta a
    Old (a -> a
    f a
    x)
        go (Delta a
    x a
    y) = a -> a -> Delta a
    forall a. a -> a -> Delta a
    Delta (a -> a
    f a
    x) a
    y
        go 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' :: forall a k. (a -> a) -> Map k (Delta a) -> Map k (Delta a)
    mapNew' 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 a
    x) = a -> Delta a
    forall a. a -> Delta a
    New (a -> a
    f a
    x)
        go (Delta a
    x a
    y) = a -> a -> Delta a
    forall a. a -> a -> Delta a
    Delta a
    x (a -> a
    f a
    y)
        go Delta a
    x = Delta a
    x
    {-# INLINE mapNew' #-}