-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Diff algorithm in pure Haskell -- -- Implementation of the standard diff algorithm in Haskell. -- -- Time complexity is O(ND) (input length * number of differences). Space -- complexity is O(D^2). Includes utilities for pretty printing. @package Diff @version 1.0.1.1 -- | This is an implementation of the diff algorithm as described in An -- <math> Difference Algorithm and Its Variations (1986) -- http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927. -- For inputs of size <math> with the number of differences -- <math> it has <math> time and <math> space -- complexity. module Data.Algorithm.Diff -- | This is PolyDiff specialized so both sides are the same type. type Diff a = PolyDiff a a -- | A value is either from the First list, the Second or -- from Both. Both contains both the left and right values, -- in case you are using a form of equality that doesn't check all data -- (for example, if you are using a newtype to only perform equality on -- side of a tuple). data PolyDiff a b First :: a -> PolyDiff a b Second :: b -> PolyDiff a b Both :: a -> b -> PolyDiff a b -- | Takes two lists and returns a list of differences between them. This -- is getDiffBy with == used as predicate. -- --
-- > getDiff ["a","b","c","d","e"] ["a","c","d","f"] -- [Both "a" "a",First "b",Both "c" "c",Both "d" "d",First "e",Second "f"] -- > getDiff "abcde" "acdf" -- [Both 'a' 'a',First 'b',Both 'c' 'c',Both 'd' 'd',First 'e',Second 'f'] --getDiff :: Eq a => [a] -> [a] -> [Diff a] -- | A form of getDiff with no Eq constraint. Instead, an -- equality predicate is taken as the first argument. getDiffBy :: (a -> b -> Bool) -> [a] -> [b] -> [PolyDiff a b] -- | Takes two lists and returns a list of differences between them, -- grouped into chunks. This is getGroupedDiffBy with == -- used as predicate. -- --
-- > getGroupedDiff "abcde" "acdf" -- [Both "a" "a",First "b",Both "cd" "cd",First "e",Second "f"] --getGroupedDiff :: Eq a => [a] -> [a] -> [Diff [a]] getGroupedDiffBy :: (a -> b -> Bool) -> [a] -> [b] -> [PolyDiff [a] [b]] instance GHC.Classes.Eq Data.Algorithm.Diff.DI instance GHC.Show.Show Data.Algorithm.Diff.DI instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Algorithm.Diff.PolyDiff a b) instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Algorithm.Diff.PolyDiff a b) instance GHC.Classes.Eq Data.Algorithm.Diff.DL instance GHC.Show.Show Data.Algorithm.Diff.DL instance GHC.Classes.Ord Data.Algorithm.Diff.DL instance GHC.Base.Functor (Data.Algorithm.Diff.PolyDiff a) instance Data.Bifunctor.Bifunctor Data.Algorithm.Diff.PolyDiff -- | Generates a grouped diff with merged runs, and outputs them in the -- manner of diff -u module Data.Algorithm.DiffContext type ContextDiff c = [Hunk c] type Hunk c = [Diff [c]] -- |
-- > let textA = ["a","b","c","d","e","f","g","h","i","j","k"] -- > let textB = ["a","b","d","e","f","g","h","i","j"] -- > let diff = getContextDiff (Just 2) textA textB -- > prettyContextDiff (text "file1") (text "file2") (text . unnumber) diff -- --- file1 -- +++ file2 -- @@ -1,5 +1,4 @@ -- a -- b -- -c -- d -- e -- @@ -9,3 +8,2 @@ -- i -- j -- -k --getContextDiff :: Eq a => Maybe Int -> [a] -> [a] -> ContextDiff (Numbered a) -- | Pretty print a ContextDiff in the manner of diff -u. prettyContextDiff :: Doc -> Doc -> (Numbered c -> Doc) -> ContextDiff (Numbered c) -> Doc prettyContextDiffOld :: Doc -> Doc -> (c -> Doc) -> ContextDiff c -> Doc getContextDiffNumbered :: Eq a => Maybe Int -> [Numbered a] -> [Numbered a] -> ContextDiff (Numbered a) data Numbered a Numbered :: Int -> a -> Numbered a numbered :: [a] -> [Numbered a] unnumber :: Numbered a -> a -- | If for some reason you need the line numbers stripped from the result -- of getContextDiff for backwards compatibility. unNumberContextDiff :: ContextDiff (Numbered a) -> ContextDiff a -- | A version of groupBy that does not assume the argument -- function is transitive. This is used to partition the Diff list -- into segments that begin and end with matching (Both) text, -- with and have non-matching (First and Second) text in -- the middle. -- --
-- let notBoth1 a b = not (a == 1 || b == 1) in -- -- groupBy' notBoth1 [1,1,2,3,1,1,4,5,6,1] -- [[1],[1,2,3,1],[1,4,5,6,1]] -- -- groupBy notBoth1 [1,1,2,3,1,1,4,5,6,1] -- [[1],[1,2,3],[1],[1,4,5,6],[1]] ---- -- In the first result the list is split anywhere there are two adjacent -- ones, as desired. groupBy' :: (a -> a -> Bool) -> [a] -> [[a]] instance GHC.Show.Show a => GHC.Show.Show (Data.Algorithm.DiffContext.Numbered a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Algorithm.DiffContext.Numbered a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Algorithm.DiffContext.Numbered a) -- | Generates a string output that is similar to diff normal mode module Data.Algorithm.DiffOutput -- | Converts Diffs to DiffOperations diffToLineRanges :: [Diff [String]] -> [DiffOperation LineRange] -- | pretty print the differences. The output is similar to the output of -- the diff utility -- --
-- > putStr (ppDiff (getGroupedDiff ["a","b","c","d","e"] ["a","c","d","f"])) -- 2d1 -- < b -- 5c4 -- < e -- --- -- > f --ppDiff :: [Diff [String]] -> String -- | pretty print of diff operations prettyDiffs :: [DiffOperation LineRange] -> Doc -- | Parse pretty printed Diffs as DiffOperations parsePrettyDiffs :: String -> [DiffOperation LineRange] -- | Line number alias type LineNo = Int -- | Line Range: start, end and contents data LineRange LineRange :: (LineNo, LineNo) -> [String] -> LineRange [lrNumbers] :: LineRange -> (LineNo, LineNo) [lrContents] :: LineRange -> [String] -- | Diff Operation representing changes to apply data DiffOperation a Deletion :: a -> LineNo -> DiffOperation a Addition :: a -> LineNo -> DiffOperation a Change :: a -> a -> DiffOperation a instance GHC.Classes.Ord Data.Algorithm.DiffOutput.LineRange instance GHC.Classes.Eq Data.Algorithm.DiffOutput.LineRange instance GHC.Read.Read Data.Algorithm.DiffOutput.LineRange instance GHC.Show.Show Data.Algorithm.DiffOutput.LineRange instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Algorithm.DiffOutput.DiffOperation a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Algorithm.DiffOutput.DiffOperation a) instance GHC.Read.Read a => GHC.Read.Read (Data.Algorithm.DiffOutput.DiffOperation a) instance GHC.Show.Show a => GHC.Show.Show (Data.Algorithm.DiffOutput.DiffOperation a)