@@ -5,16 +5,19 @@
5{-# LANGUAGE DeriveFunctor #-}
5{-# LANGUAGE DeriveFunctor #-}
6{-# LANGUAGE DeriveTraversable #-}
6{-# LANGUAGE DeriveTraversable #-}
7{-# LANGUAGE FlexibleContexts #-}
7{-# LANGUAGE FlexibleContexts #-}
8+{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE GADTs #-}
9{-# LANGUAGE GADTs #-}
9{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10{-# LANGUAGE LambdaCase #-}
11{-# LANGUAGE LambdaCase #-}
12+{-# LANGUAGE MultiParamTypeClasses #-}
11{-# LANGUAGE PolyKinds #-}
13{-# LANGUAGE PolyKinds #-}
12{-# LANGUAGE Rank2Types #-}
14{-# LANGUAGE Rank2Types #-}
13{-# LANGUAGE ScopedTypeVariables #-}
15{-# LANGUAGE ScopedTypeVariables #-}
14{-# LANGUAGE StandaloneDeriving #-}
16{-# LANGUAGE StandaloneDeriving #-}
15{-# LANGUAGE TypeFamilies #-}
17{-# LANGUAGE TypeFamilies #-}
18+{-# LANGUAGE UndecidableInstances #-}
16module Reflex.Patch
19module Reflex.Patch
17− ( Patch (..)
20+{- ( Patch (..)
18 , PatchDMap (..)
21 , PatchDMap (..)
19 , mapPatchDMap
22 , mapPatchDMap
20 , traversePatchDMap
23 , traversePatchDMap
@@ -36,7 +39,7 @@ module Reflex.Patch
36 , mapEditMoved
39 , mapEditMoved
37 , mapEditSetMoved
40 , mapEditSetMoved
38 , PatchDMapWithMove
41 , PatchDMapWithMove
39− , unPatchDMapWithMove
42+-- , unPatchDMapWithMove
40 , unsafePatchDMapWithMove
43 , unsafePatchDMapWithMove
41 , patchThatSortsMapWith
44 , patchThatSortsMapWith
42 , patchThatChangesAndSortsMapWith
45 , patchThatChangesAndSortsMapWith
@@ -52,17 +55,20 @@ module Reflex.Patch
52 , validPatchMapWithMove
55 , validPatchMapWithMove
53 , knownValidPatchMapWithMove
56 , knownValidPatchMapWithMove
54 , knownInvalidPatchMapWithMove
57 , knownInvalidPatchMapWithMove
55− ) where
58+ ) -} where
57import Control.Arrow
60import Control.Arrow
58import Control.Monad.Identity
61import Control.Monad.Identity
59import Control.Monad.State
62import Control.Monad.State
60import Data.Dependent.Map (DMap, DSum (..), GCompare (..))
63import Data.Dependent.Map (DMap, DSum (..), GCompare (..))
61import qualified Data.Dependent.Map as DMap
64import qualified Data.Dependent.Map as DMap
65+import Data.Dependent.Sum (ShowTag (..), ReadTag (..), EqTag (..), OrdTag (..))
62import Data.Foldable
66import Data.Foldable
63import Data.Function
67import Data.Function
64import Data.Functor.Constant
68import Data.Functor.Constant
65import Data.Functor.Misc
69import Data.Functor.Misc
70+import Data.GADT.Compare (GEq (..))
71+import Data.GADT.Show (GShow (..))
66import Data.List
72import Data.List
67import Data.Map (Map)
73import Data.Map (Map)
68import qualified Data.Map as Map
74import qualified Data.Map as Map
@@ -72,6 +78,7 @@ import qualified Data.Set as Set
72import Data.Some (Some)
78import Data.Some (Some)
73import qualified Data.Some as Some
79import qualified Data.Some as Some
74import Data.Tuple
80import Data.Tuple
81+import Data.Typeable (Proxy (..))
76-- | A 'Patch' type represents a kind of change made to a datastructure.
83-- | A 'Patch' type represents a kind of change made to a datastructure.
77class Patch p where
84class Patch p where
@@ -80,10 +87,16 @@ class Patch p where
80 -- 'Nothing'.
87 -- 'Nothing'.
81 apply :: p -> PatchTarget p -> Maybe (PatchTarget p)
88 apply :: p -> PatchTarget p -> Maybe (PatchTarget p)
90+applyAlways :: Patch p => p -> PatchTarget p -> PatchTarget p
91+applyAlways p t = fromMaybe t $ apply p t
83-- | We can't use @Compose Maybe@ instead of 'ComposeMaybe', because that would
93-- | We can't use @Compose Maybe@ instead of 'ComposeMaybe', because that would
84-- make the 'f' parameter have a nominal type role. We need f to be
94-- make the 'f' parameter have a nominal type role. We need f to be
85-- representational so that we can use safe 'coerce'.
95-- representational so that we can use safe 'coerce'.
86−newtype ComposeMaybe f a = ComposeMaybe { getComposeMaybe :: Maybe (f a) }
96+newtype ComposeMaybe f a = ComposeMaybe { getComposeMaybe :: Maybe (f a) } deriving (Show, Eq)
98+instance EqTag f g => EqTag f (ComposeMaybe g) where
99+ eqTagToEq f p r = eqTagToEq f (Proxy :: Proxy g) r
88deriving instance Functor f => Functor (ComposeMaybe f)
101deriving instance Functor f => Functor (ComposeMaybe f)
@@ -183,18 +196,18 @@ instance Additive p => Patch (AdditivePatch p) where
183 apply (AdditivePatch p) q = Just $ p <> q
196 apply (AdditivePatch p) q = Just $ p <> q
185data MapEdit k v
198data MapEdit k v
186− = MapEdit_Insert Bool v -- ^ Insert the given value here
199+ = MapEdit_Insert (Maybe k) v -- ^ Insert the given value here
187− | MapEdit_Delete Bool -- ^ Delete the existing value, if any, from here
200+ | MapEdit_Delete (Maybe k) -- ^ Delete the existing value, if any, from here
188− | MapEdit_Move Bool k -- ^ Move the value here from the given key
201+ | MapEdit_Move (Maybe k) k -- ^ Move the value here from the given key
189 deriving (Show, Read, Eq, Ord, Functor, Foldable, Traversable)
202 deriving (Show, Read, Eq, Ord, Functor, Foldable, Traversable)
191mapEditMoved :: MapEdit k v -> Bool
204mapEditMoved :: MapEdit k v -> Bool
192−mapEditMoved = \case
205+mapEditMoved = isJust . \case
193 MapEdit_Insert moved _ -> moved
206 MapEdit_Insert moved _ -> moved
194 MapEdit_Delete moved -> moved
207 MapEdit_Delete moved -> moved
195 MapEdit_Move moved _ -> moved
208 MapEdit_Move moved _ -> moved
197−mapEditSetMoved :: Bool -> MapEdit k v -> MapEdit k v
210+mapEditSetMoved :: Maybe k -> MapEdit k v -> MapEdit k v
198mapEditSetMoved moved = \case
211mapEditSetMoved moved = \case
199 MapEdit_Insert _ v -> MapEdit_Insert moved v
212 MapEdit_Insert _ v -> MapEdit_Insert moved v
200 MapEdit_Delete _ -> MapEdit_Delete moved
213 MapEdit_Delete _ -> MapEdit_Delete moved
@@ -249,29 +262,33 @@ knownValidPatchMapWithMove :: [PatchMapWithMove Int Int]
249knownValidPatchMapWithMove =
262knownValidPatchMapWithMove =
250 [ PatchMapWithMove mempty
263 [ PatchMapWithMove mempty
251 , PatchMapWithMove $ Map.fromList
264 , PatchMapWithMove $ Map.fromList
252− [ (1, MapEdit_Move True 2)
265+ [ (1, MapEdit_Move (Just 1) 2)
253− , (2, MapEdit_Move True 1)
266+ , (2, MapEdit_Move (Just 2) 1)
257knownInvalidPatchMapWithMove :: [PatchMapWithMove Int Int]
270knownInvalidPatchMapWithMove :: [PatchMapWithMove Int Int]
258knownInvalidPatchMapWithMove =
271knownInvalidPatchMapWithMove =
259 [ -- Invalid because we move 2 to 1, but don't specify what to do with 2
272 [ -- Invalid because we move 2 to 1, but don't specify what to do with 2
260− PatchMapWithMove $ Map.singleton 1 $ MapEdit_Move False 2
273+ PatchMapWithMove $ Map.singleton 1 $ MapEdit_Move Nothing 2
261 , -- Invalid because we have multiple moves from 3
274 , -- Invalid because we have multiple moves from 3
262 PatchMapWithMove $ Map.fromList
275 PatchMapWithMove $ Map.fromList
263− [ (1, MapEdit_Move False 3)
276+ [ (1, MapEdit_Move Nothing 3)
264− , (2, MapEdit_Move False 3)
277+ , (2, MapEdit_Move Nothing 3)
265− , (3, MapEdit_Delete True)
278+ , (3, MapEdit_Delete (Just 1))
269patchThatSortsMapWith :: Ord k => (v -> v -> Ordering) -> Map k v -> PatchMapWithMove k v
282patchThatSortsMapWith :: Ord k => (v -> v -> Ordering) -> Map k v -> PatchMapWithMove k v
270−patchThatSortsMapWith cmp m = PatchMapWithMove $ Map.fromList $ catMaybes $ zipWith g l $ sortBy (cmp `on` snd) l
283+patchThatSortsMapWith cmp m = PatchMapWithMove $ Map.fromList $ catMaybes $ zipWith g unsorted sorted
271− where l = Map.toList m
284+ where unsorted = Map.toList m
285+ sorted = sortBy (cmp `on` snd) unsorted
286+ f (to, _) (from, _) = if to == from then Nothing else
288+ reverseMapping = Map.fromList $ catMaybes $ zipWith f unsorted sorted
272− g (to, _) (from, _) = if to == from
289+ g (to, _) (from, _) = if to == from then Nothing else
273− then Nothing
290+ let Just movingTo = Map.lookup from reverseMapping
274− else Just (to, MapEdit_Move True from)
291+ in Just (to, MapEdit_Move (Just movingTo) from)
276patchThatChangesAndSortsMapWith :: (Ord k, Ord v) => (v -> v -> Ordering) -> Map k v -> Map k v -> PatchMapWithMove k v
293patchThatChangesAndSortsMapWith :: (Ord k, Ord v) => (v -> v -> Ordering) -> Map k v -> Map k v -> PatchMapWithMove k v
277patchThatChangesAndSortsMapWith cmp oldByIndex newByIndexUnsorted = patch
294patchThatChangesAndSortsMapWith cmp oldByIndex newByIndexUnsorted = patch
@@ -285,41 +302,160 @@ patchThatChangesAndSortsMapWith cmp oldByIndex newByIndexUnsorted = patch
285 then Map.delete v remainingValues
302 then Map.delete v remainingValues
286 else Map.insert v remainingKeys remainingValues
303 else Map.insert v remainingKeys remainingValues
287 case Map.lookup v remainingValues of
304 case Map.lookup v remainingValues of
288− Nothing -> return $ MapEdit_Insert True v -- There's no existing value we can take
305+ Nothing -> return $ MapEdit_Insert (Just undefined) v -- There's no existing value we can take
289 Just fromKs ->
306 Just fromKs ->
290 if k `Set.member` fromKs
307 if k `Set.member` fromKs
292 putRemainingKeys $ Set.delete k fromKs
309 putRemainingKeys $ Set.delete k fromKs
293− return $ MapEdit_Move True k -- There's an existing value, and it's here, so no patch necessary
310+ return $ MapEdit_Move (Just undefined) k -- There's an existing value, and it's here, so no patch necessary
295 Just (fromK, remainingKeys) <- return $ Set.minView fromKs -- There's an existing value, but it's not here; move it here
312 Just (fromK, remainingKeys) <- return $ Set.minView fromKs -- There's an existing value, but it's not here; move it here
296 putRemainingKeys remainingKeys
313 putRemainingKeys remainingKeys
297− return $ MapEdit_Move True fromK
314+ return $ MapEdit_Move (Just undefined) fromK
298 Map.traverseWithKey f newByIndex
315 Map.traverseWithKey f newByIndex
299 unusedOldKeys = fold unusedValuesByValue
316 unusedOldKeys = fold unusedValuesByValue
300 pointlessMove k = \case
317 pointlessMove k = \case
301 MapEdit_Move _ k' | k == k' -> True
318 MapEdit_Move _ k' | k == k' -> True
302 _ -> False
319 _ -> False
303− keyWasMoved k = k `Map.member` oldByIndex && not (k `Set.member` unusedOldKeys)
320+ keyWasMoved k = if k `Map.member` oldByIndex && not (k `Set.member` unusedOldKeys)
304 patch = unsafePatchMapWithMove $ Map.filterWithKey (\k v -> not $ pointlessMove k v) $ Map.mergeWithKey (\k a _ -> Just $ mapEditSetMoved (keyWasMoved k) a) (Map.mapWithKey $ \k -> mapEditSetMoved $ keyWasMoved k) (Map.mapWithKey $ \k _ -> MapEdit_Delete $ keyWasMoved k) insertsAndMoves oldByIndex
323 patch = unsafePatchMapWithMove $ Map.filterWithKey (\k v -> not $ pointlessMove k v) $ Map.mergeWithKey (\k a _ -> Just $ mapEditSetMoved (keyWasMoved k) a) (Map.mapWithKey $ \k -> mapEditSetMoved $ keyWasMoved k) (Map.mapWithKey $ \k _ -> MapEdit_Delete $ keyWasMoved k) insertsAndMoves oldByIndex
306data DMapEdit (k :: a -> *) (v :: a -> *) :: a -> * where
325data DMapEdit (k :: a -> *) (v :: a -> *) :: a -> * where
307 -- | Insert the given value here
326 -- | Insert the given value here
308− DMapEdit_Insert :: Bool -> v a -> DMapEdit k v a
327+ DMapEdit_Insert :: v a -> DMapEdit k v a
309 -- | Delete the existing value, if any, from here
328 -- | Delete the existing value, if any, from here
310− DMapEdit_Delete :: Bool -> DMapEdit k v a
329+ DMapEdit_Delete :: DMapEdit k v a
311 -- | Move the value here from the given key
330 -- | Move the value here from the given key
312− DMapEdit_Move :: Bool -> k a -> DMapEdit k v a
331+ DMapEdit_Move :: k a -> DMapEdit k v a
332+ deriving (Show, Read, Eq, Ord)
334+instance {-# INCOHERENT #-} (GShow k, ShowTag k v) => ShowTag k (DMapEdit k v) where
335+ showTagToShow k _ r = gshowToShow k $ showTagToShow k (Proxy :: Proxy v) r
337+instance {-# INCOHERENT #-} GShow k => ShowTag k (ComposeMaybe k) where
338+ showTagToShow k _ r = gshowToShow k (showTagToShow k (Proxy :: Proxy k) r)
340+instance (GEq k, EqTag k v) => EqTag k (DMapEdit k v) where
341+ eqTagToEq k p r = eqTagToEq k (Proxy :: Proxy v) (geqToEq k r)
314dmapEditMoved :: DMapEdit k v a -> Bool
344dmapEditMoved :: DMapEdit k v a -> Bool
315−dmapEditMoved = \case
345+dmapEditMoved = isJust . dmapEditMovedTo
347+dmapEditMovedTo :: DMapEdit k v a -> Maybe (k a)
348+dmapEditMovedTo = \case
316 DMapEdit_Insert moved _ -> moved
349 DMapEdit_Insert moved _ -> moved
317 DMapEdit_Delete moved -> moved
350 DMapEdit_Delete moved -> moved
318 DMapEdit_Move moved _ -> moved
351 DMapEdit_Move moved _ -> moved
320-- | Like 'PatchMapWithMove', but for 'DMap'.
354-- | Like 'PatchMapWithMove', but for 'DMap'.
321−newtype PatchDMapWithMove k v = PatchDMapWithMove (DMap k (DMapEdit k v))
355+data PatchDMapWithMove k v = PatchDMapWithMove (DMap k (DMapEdit k v)) (DMap k (ComposeMaybe k))
358+validPatchDMapWithMove :: forall k v. (GCompare k, EqTag k (ComposeMaybe k)) => PatchDMapWithMove k v -> Bool
359+validPatchDMapWithMove (PatchDMapWithMove dst src) = src == srcFromDst
361+ srcFromDst :: DMap k (ComposeMaybe k)
362+ srcFromDst = DMap.fromList $ flip fmap (DMap.toList dst) $ \(to :=> edit) -> case edit of
363+ DMapEdit_Move from -> from :=> ComposeMaybe (Just to)
364+ _ -> to :=> ComposeMaybe Nothing
366+instance (Eq k, Eq v) => EqTag (Const2 k v) Identity where
367+ eqTagToEq (Const2 _) _ = id
369+instance (Eq k, Eq v) => EqTag (Const2 k v) (Const2 k v) where
370+ eqTagToEq (Const2 _) _ = id
372+moveDMapKey :: GCompare k => k a -> k a -> PatchDMapWithMove k v
373+moveDMapKey src dst = case src `geq` dst of
374+ Nothing -> PatchDMapWithMove (DMap.fromList [dst :=> DMapEdit_Move src, src :=> DMapEdit_Delete]) (DMap.fromList [src :=> ComposeMaybe (Just dst), dst :=> ComposeMaybe Nothing])
377+deleteDMapKey :: k a -> PatchDMapWithMove k v
378+deleteDMapKey k = PatchDMapWithMove (DMap.singleton k DMapEdit_Delete) $ DMap.singleton k $ ComposeMaybe Nothing
381+k1, k2 :: Const2 Int () ()
384+p1, p2 :: PatchDMapWithMove (Const2 Int ()) Identity
385+p1 = moveDMapKey k1 k2
386+p2 = moveDMapKey k2 k1
389+p12Slow = p1 `mappendPatchDMapWithMoveSlow` p2
390+p21Slow = p2 `mappendPatchDMapWithMoveSlow` p1
392+testPatchDMapWithMove = do
395+ print $ p12 == deleteDMapKey k1
396+ print $ p21 == deleteDMapKey k2
397+ print $ p12Slow == deleteDMapKey k1
398+ print $ p21Slow == deleteDMapKey k2
400+dst (PatchDMapWithMove x _) = x
401+src (PatchDMapWithMove _ x) = x
404+instance (EqTag k k, EqTag k v, EqTag k (ComposeMaybe k)) => Eq (PatchDMapWithMove k v) where
405+ PatchDMapWithMove dstA srcA == PatchDMapWithMove dstB srcB = dstA == dstB && srcA == srcB
407+data Pair1 f g a = Pair1 (f a) (g a)
409+instance GCompare k => Semigroup (PatchDMapWithMove k v) where
412+instance GCompare k => Monoid (PatchDMapWithMove k v) where
413+ mempty = PatchDMapWithMove mempty mempty
414+ PatchDMapWithMove dstAfter srcAfter `mappend` PatchDMapWithMove dstBefore srcBefore = PatchDMapWithMove dst src
416+ connections = DMap.toList $ DMap.intersectionWithKey (const Pair1) srcAfter dstBefore
417+ f :: DSum k (Pair1 (ComposeMaybe k) (DMapEdit k v)) -> Maybe (DSum k (ComposeMaybe (DMapEdit k v)))
418+ f (k :=> Pair1 (ComposeMaybe mToAfter) editBefore) = case mToAfter of
419+ Nothing -> Nothing -- Since the result of this connection was simply discarded, we don't need to change dst
420+ Just toAfter -> Just $ (toAfter :=>) $ ComposeMaybe $ case editBefore of
421+ DMapEdit_Move fromBefore -> if isJust $ fromBefore `geq` toAfter
422+ then Nothing -- The two moves have canceled out, so eliminate the destination entry
423+ else Just editBefore
424+ nonMove -> Just editBefore
425+ dstPatch = PatchDMap $ DMap.fromList $ catMaybes $ f <$> connections
426+ dst = applyAlways dstPatch $ DMap.union dstAfter dstBefore
427+ g :: DSum k (Pair1 (ComposeMaybe k) (DMapEdit k v)) -> Maybe (DSum k (ComposeMaybe (ComposeMaybe k)))
428+ g (k :=> Pair1 (ComposeMaybe mToAfter) editBefore) = case editBefore of
429+ DMapEdit_Move fromBefore -> Just $ (fromBefore :=>) $ ComposeMaybe $ case mToAfter of
430+ Nothing -> Just $ ComposeMaybe Nothing -- The item is destroyed in the second patch, so indicate that it is destroyed in the source map
431+ Just toAfter -> if isJust $ toAfter `geq` fromBefore
432+ then Nothing -- The two moves have canceled out, so eliminate the source entry
433+ else Just $ ComposeMaybe mToAfter
434+ _ -> Nothing --TODO: Is this right?
435+ srcPatch = PatchDMap $ DMap.fromList $ catMaybes $ g <$> connections
436+ src = applyAlways srcPatch $ DMap.union srcBefore srcAfter
438+mappendPatchDMapWithMoveSlow :: forall k v. (ShowTag k v, GCompare k) => PatchDMapWithMove k v -> PatchDMapWithMove k v -> PatchDMapWithMove k v
439+PatchDMapWithMove dstAfter srcAfter `mappendPatchDMapWithMoveSlow` PatchDMapWithMove dstBefore srcBefore = PatchDMapWithMove dst src
441+ getDstAction k m = fromMaybe (DMapEdit_Move k) $ DMap.lookup k m -- Any key that isn't present is treated as that key moving to itself
442+ removeRedundantDst toKey (DMapEdit_Move fromKey) | isJust (toKey `geq` fromKey) = Nothing
443+ removeRedundantDst _ a = Just a
444+ f :: forall a. k a -> DMapEdit k v a -> Maybe (DMapEdit k v a)
445+ f toKey _ = removeRedundantDst toKey $ case getDstAction toKey dstAfter of
446+ DMapEdit_Move fromKey -> getDstAction fromKey dstBefore
448+ dst = DMap.mapMaybeWithKey f $ DMap.union dstAfter dstBefore
449+ getSrcAction k m = fromMaybe (ComposeMaybe $ Just k) $ DMap.lookup k m
450+ removeRedundantSrc fromKey (ComposeMaybe (Just toKey)) | isJust (fromKey `geq` toKey) = Nothing
451+ removeRedundantSrc _ a = Just a
452+ g :: forall a. k a -> ComposeMaybe k a -> Maybe (ComposeMaybe k a)
453+ g fromKey _ = removeRedundantSrc fromKey $ case getSrcAction fromKey srcBefore of
454+ ComposeMaybe Nothing -> ComposeMaybe Nothing
455+ ComposeMaybe (Just toKeyBefore) -> getSrcAction toKeyBefore srcAfter
456+ src = DMap.mapMaybeWithKey g $ DMap.union srcAfter srcBefore
323unPatchDMapWithMove :: PatchDMapWithMove k v -> DMap k (DMapEdit k v)
459unPatchDMapWithMove :: PatchDMapWithMove k v -> DMap k (DMapEdit k v)
324unPatchDMapWithMove (PatchDMapWithMove p) = p
460unPatchDMapWithMove (PatchDMapWithMove p) = p
@@ -327,6 +463,28 @@ unPatchDMapWithMove (PatchDMapWithMove p) = p
327-- 'PatchDMapWithMove' are preserved; they will not be checked.
463-- 'PatchDMapWithMove' are preserved; they will not be checked.
328unsafePatchDMapWithMove :: DMap k (DMapEdit k v) -> PatchDMapWithMove k v
464unsafePatchDMapWithMove :: DMap k (DMapEdit k v) -> PatchDMapWithMove k v
329unsafePatchDMapWithMove = PatchDMapWithMove
465unsafePatchDMapWithMove = PatchDMapWithMove
469+instance GCompare k => Monoid (PatchDMapWithMove k v) where
470+ mempty = PatchDMapWithMove mempty
471+ PatchDMapWithMove a `mappend` PatchDMapWithMove b = PatchDMapWithMove $ DMap.unionWithKey f a b
472+ where f :: forall a. k a -> DMapEdit k v a -> DMapEdit k v a -> DMapEdit k v a
473+ f _ ea eb = case (ea, eb) of
474+ (DMapEdit_Delete _, DMapEdit_Delete moved) -> DMapEdit_Delete $ do
476+ case DMap.lookup dst a of
477+ Nothing -> return dst
478+ Just dstChange -> dmapEditMovedTo dstChange
479+ (DMapEdit_Move _ from, DMapEdit_Delete moved) -> DMapEdit_Move moved from
480+ (DMapEdit_Insert _ v, DMapEdit_Delete moved) -> DMapEdit_Insert moved v
481+ (DMapEdit_Delete _, DMapEdit_Insert moved v) -> DMapEdit_Delete moved
482+ (DMapEdit_Move _ from, DMapEdit_Insert moved v) -> DMapEdit_Move moved from
483+ (DMapEdit_Insert _ newV, DMapEdit_Insert moved oldV) -> DMapEdit_Insert moved newV
484+ (DMapEdit_Delete _, DMapEdit_Move moved k) -> DMapEdit_Delete moved
331mapPatchDMapWithMove :: forall k v v'. (forall a. v a -> v' a) -> PatchDMapWithMove k v -> PatchDMapWithMove k v'
489mapPatchDMapWithMove :: forall k v v'. (forall a. v a -> v' a) -> PatchDMapWithMove k v -> PatchDMapWithMove k v'
332mapPatchDMapWithMove f (PatchDMapWithMove p) = PatchDMapWithMove $ DMap.map g p
490mapPatchDMapWithMove f (PatchDMapWithMove p) = PatchDMapWithMove $ DMap.map g p
@@ -351,25 +509,25 @@ weakenPatchDMapWithMoveWith :: forall k v v'. (forall a. v a -> v') -> PatchDMap
351weakenPatchDMapWithMoveWith f (PatchDMapWithMove p) = PatchMapWithMove $ weakenDMapWith g p
509weakenPatchDMapWithMoveWith f (PatchDMapWithMove p) = PatchMapWithMove $ weakenDMapWith g p
352 where g :: forall a. DMapEdit k v a -> MapEdit (Some k) v'
510 where g :: forall a. DMapEdit k v a -> MapEdit (Some k) v'
353 g = \case
511 g = \case
354− DMapEdit_Insert moved v -> MapEdit_Insert moved $ f v
512+ DMapEdit_Insert moved v -> MapEdit_Insert (Some.This <$> moved) $ f v
355− DMapEdit_Delete moved -> MapEdit_Delete moved
513+ DMapEdit_Delete moved -> MapEdit_Delete $ Some.This <$> moved
356− DMapEdit_Move moved k -> MapEdit_Move moved $ Some.This k
514+ DMapEdit_Move moved k -> MapEdit_Move (Some.This <$> moved) $ Some.This k
358patchDMapWithMoveToPatchMapWithMoveWith :: forall k f v v'. (f v -> v') -> PatchDMapWithMove (Const2 k v) f -> PatchMapWithMove k v'
516patchDMapWithMoveToPatchMapWithMoveWith :: forall k f v v'. (f v -> v') -> PatchDMapWithMove (Const2 k v) f -> PatchMapWithMove k v'
359patchDMapWithMoveToPatchMapWithMoveWith f (PatchDMapWithMove p) = PatchMapWithMove $ dmapToMapWith g p
517patchDMapWithMoveToPatchMapWithMoveWith f (PatchDMapWithMove p) = PatchMapWithMove $ dmapToMapWith g p
360 where g :: DMapEdit (Const2 k v) f v -> MapEdit k v'
518 where g :: DMapEdit (Const2 k v) f v -> MapEdit k v'
361 g = \case
519 g = \case
362− DMapEdit_Insert moved v -> MapEdit_Insert moved $ f v
520+ DMapEdit_Insert moved v -> MapEdit_Insert (unConst2 <$> moved) $ f v
363− DMapEdit_Delete moved -> MapEdit_Delete moved
521+ DMapEdit_Delete moved -> MapEdit_Delete $ unConst2 <$> moved
364− DMapEdit_Move moved (Const2 k) -> MapEdit_Move moved k
522+ DMapEdit_Move moved (Const2 k) -> MapEdit_Move (unConst2 <$> moved) k
366const2PatchDMapWithMoveWith :: forall k v f a. (v -> f a) -> PatchMapWithMove k v -> PatchDMapWithMove (Const2 k a) f
524const2PatchDMapWithMoveWith :: forall k v f a. (v -> f a) -> PatchMapWithMove k v -> PatchDMapWithMove (Const2 k a) f
367const2PatchDMapWithMoveWith f (PatchMapWithMove p) = PatchDMapWithMove $ DMap.fromDistinctAscList $ g <$> Map.toAscList p
525const2PatchDMapWithMoveWith f (PatchMapWithMove p) = PatchDMapWithMove $ DMap.fromDistinctAscList $ g <$> Map.toAscList p
368 where g :: (k, MapEdit k v) -> DSum (Const2 k a) (DMapEdit (Const2 k a) f)
526 where g :: (k, MapEdit k v) -> DSum (Const2 k a) (DMapEdit (Const2 k a) f)
369 g (k, e) = Const2 k :=> case e of
527 g (k, e) = Const2 k :=> case e of
370− MapEdit_Insert moved v -> DMapEdit_Insert moved $ f v
528+ MapEdit_Insert moved v -> DMapEdit_Insert (Const2 <$> moved) $ f v
371− MapEdit_Delete moved -> DMapEdit_Delete moved
529+ MapEdit_Delete moved -> DMapEdit_Delete $ Const2 <$> moved
372− MapEdit_Move moved fromKey -> DMapEdit_Move moved $ Const2 fromKey
530+ MapEdit_Move moved fromKey -> DMapEdit_Move (Const2 <$> moved) $ Const2 fromKey
374instance GCompare k => Patch (PatchDMapWithMove k v) where
532instance GCompare k => Patch (PatchDMapWithMove k v) where
375 type PatchTarget (PatchDMapWithMove k v) = DMap k v
533 type PatchTarget (PatchDMapWithMove k v) = DMap k v
@@ -385,3 +543,4 @@ instance GCompare k => Patch (PatchDMapWithMove k v) where
385 deleteFunc _ = \case
543 deleteFunc _ = \case
386 DMapEdit_Delete _ -> Just $ Constant ()
544 DMapEdit_Delete _ -> Just $ Constant ()
387 _ -> Nothing
545 _ -> Nothing