packages feed

patches-vector 0.1.3.0 → 0.1.4.0

raw patch · 3 files changed

+39/−6 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Patch: composable :: Eq a => Patch a -> Patch a -> Bool
+ Data.Patch.Internal: composable :: Eq a => Patch a -> Patch a -> Bool

Files

Data/Patch.hs view
@@ -7,16 +7,17 @@        , fromList        , unsafeFromList        , inverse+       , composable+         -- * Documents+       , apply+       , applicable+       , diff          -- ** Transformations and merges        , transformWith          -- *** Conflict strategies        , transform        , ours        , theirs-         -- * Documents-       , apply-       , applicable-       , diff          -- * Edits        , Edit (..)        , index
Data/Patch/Internal.hs view
@@ -100,6 +100,10 @@ -- prop> forAll (patchesFrom d) $ \p -> inverse mempty == mempty -- -- prop> forAll (patchesFrom d) $ \p -> applicable (inverse p) (apply p d)+--+-- prop> forAll (patchesFrom d) $ \p -> composable p (inverse p)+--+-- prop> forAll (patchesFrom d) $ \p -> composable (inverse p) p inverse :: Patch a -> Patch a inverse (Patch ls) = Patch $ snd $ List.mapAccumL go 0 ls   where@@ -203,6 +207,34 @@                                     Just c' | c == c' -> True                                     _ -> False +-- | Returns true if a patch can be validly composed with another.+--   That is, @composable p q@ holds if @q@ can be validly applied after @p@.+--+--   prop> forAll (patchesFrom d) $ \p -> composable mempty p+--   prop> forAll (patchesFrom d) $ \p -> composable p mempty+--   prop> forAll (historyFrom d 2) $ \[p, q] -> composable p q+composable :: Eq a => Patch a -> Patch a -> Bool+composable (Patch a) (Patch b) = go a b (0 :: Int)+    where+      go [] _ _  = True+      go _ [] _    = True+      go (x:xs) (y:ys) off = let+          y' = over index (+ off) y+        in case comparing (^. index) x y' of+         LT -> go xs (y:ys) (off + offset x)+         GT -> go (x:xs) ys off+         EQ -> case (x,y') of+             (Delete {}, Insert {}) -> go xs ys (off + offset x)+             (Delete {}, _) -> go xs (y:ys) (off + offset x)+             (_, Insert {}) -> go (x:xs) ys off+             (Replace _ _ o, Replace _ n _) -> o == n && go xs ys off+             (Replace _ _ o, Delete _ n) -> o == n && go xs ys off+             (Insert _ o, Replace _ n _) -> o == n && go xs ys (off + offset x)+             (Insert _ o, Delete _ n) -> o == n && go xs ys (off + offset x)+      offset (Insert {}) = -1+      offset (Delete {}) = 1+      offset (Replace {}) = 0+ -- | Apply a patch to a document. -- -- Technically, 'apply' is a /monoid morphism/ to the monoid of endomorphisms @Vector a -> Vector a@,@@ -247,6 +279,7 @@ -- --   prop> forAll (divergingPatchesFrom d) $ \(p,q) -> let (p', q') = transformWith ours p q in apply (p <> q') d == apply (q <> p') d --   prop> forAll (divergingPatchesFrom d) $ \(p,q) -> let (p', q') = transformWith ours p q in applicable p' (apply q d) && applicable q' (apply p d)+--   prop> forAll (divergingPatchesFrom d) $ \(p,q) -> let (p', q') = transformWith ours p q in composable p q' && composable q p' -- --   This function is commutative iff @m@ is commutative. --@@ -310,7 +343,6 @@ -- prop> apply (diff a b <> diff b c) a == apply (diff a c) a -- -- prop> applicable (diff a b) a--- diff :: Eq a => Vector a -> Vector a -> Patch a diff v1 v2 = let (_ , s) = leastChanges params v1 v2               in unsafeFromList $ adjust 0 $ s
patches-vector.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                patches-vector-version:             0.1.3.0+version:             0.1.4.0 synopsis:            Patches (diffs) on vectors: composable, mergeable, and invertible. description:         A patch is a collection of modifications (edits) to be made to a sequence of elements. Commonly                      found in version control systems, patches are also a simple example of a group, supporting composition