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 +5/−4
- Data/Patch/Internal.hs +33/−1
- patches-vector.cabal +1/−1
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