    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Algorithm.DiffOutput
    -- Copyright   :  (c) Sterling Clover 2008-2011, Kevin Charter 2011
    -- License     :  BSD 3 Clause
    -- Maintainer  :  s.clover@gmail.com
    -- Stability   :  experimental
    -- Portability :  portable
    -- Author      :  Stephan Wehr (wehr@factisresearch.com) and JP Moresmau (jp@moresmau.fr)
    --
    -- Generates a string output that is similar to diff normal mode
    -----------------------------------------------------------------------------
    module Data.Algorithm.DiffOutput where
    import Data.Algorithm.Diff
    import Text.PrettyPrint hiding ((<>))
    import Data.Char
    import Data.List

    -- | Converts Diffs to DiffOperations
    diffToLineRanges :: [Diff [String]] -> [DiffOperation LineRange]
    diffToLineRanges :: [Diff [String]] -> [DiffOperation LineRange]
    diffToLineRanges = LineNo -> LineNo -> [Diff [String]] -> [DiffOperation LineRange]
    toLineRange LineNo
    1 LineNo
    1
       where
              toLineRange :: Int -> Int -> [Diff [String]] -> [DiffOperation LineRange]
              toLineRange :: LineNo -> LineNo -> [Diff [String]] -> [DiffOperation LineRange]
    toLineRange LineNo
    _ LineNo
    _ []=[]
              toLineRange LineNo
    leftLine LineNo
    rightLine (Both [String]
    ls [String]
    _:[Diff [String]]
    rs)=
                    let lins :: LineNo
    lins=[String] -> LineNo
    forall a. [a] -> LineNo
    forall (t :: * -> *) a. Foldable t => t a -> LineNo
    length [String]
    ls
                    in  LineNo -> LineNo -> [Diff [String]] -> [DiffOperation LineRange]
    toLineRange (LineNo
    leftLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    lins) (LineNo
    rightLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    lins) [Diff [String]]
    rs
              toLineRange LineNo
    leftLine LineNo
    rightLine (Second [String]
    lsS:First [String]
    lsF:[Diff [String]]
    rs)=
                    LineNo
    -> LineNo
    -> [String]
    -> [String]
    -> [Diff [String]]
    -> [DiffOperation LineRange]
    toChange LineNo
    leftLine LineNo
    rightLine [String]
    lsF [String]
    lsS [Diff [String]]
    rs
              toLineRange LineNo
    leftLine LineNo
    rightLine (First [String]
    lsF:Second [String]
    lsS:[Diff [String]]
    rs)=
                    LineNo
    -> LineNo
    -> [String]
    -> [String]
    -> [Diff [String]]
    -> [DiffOperation LineRange]
    toChange LineNo
    leftLine LineNo
    rightLine [String]
    lsF [String]
    lsS [Diff [String]]
    rs
              toLineRange LineNo
    leftLine LineNo
    rightLine (Second [String]
    lsS:[Diff [String]]
    rs)=
                    let linesS :: LineNo
    linesS=[String] -> LineNo
    forall a. [a] -> LineNo
    forall (t :: * -> *) a. Foldable t => t a -> LineNo
    length [String]
    lsS
                        diff :: DiffOperation LineRange
    diff=LineRange -> LineNo -> DiffOperation LineRange
    forall a. a -> LineNo -> DiffOperation a
    Addition ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo
    rightLine,LineNo
    rightLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesSLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    -LineNo
    1) [String]
    lsS) (LineNo
    leftLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    -LineNo
    1)
                    in  DiffOperation LineRange
    diff DiffOperation LineRange
    -> [DiffOperation LineRange] -> [DiffOperation LineRange]
    forall a. a -> [a] -> [a]
    : LineNo -> LineNo -> [Diff [String]] -> [DiffOperation LineRange]
    toLineRange LineNo
    leftLine (LineNo
    rightLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesS) [Diff [String]]
    rs
              toLineRange LineNo
    leftLine LineNo
    rightLine  (First [String]
    lsF:[Diff [String]]
    rs)=
                    let linesF :: LineNo
    linesF=[String] -> LineNo
    forall a. [a] -> LineNo
    forall (t :: * -> *) a. Foldable t => t a -> LineNo
    length [String]
    lsF
                        diff :: DiffOperation LineRange
    diff=LineRange -> LineNo -> DiffOperation LineRange
    forall a. a -> LineNo -> DiffOperation a
    Deletion ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo
    leftLine,LineNo
    leftLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesFLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    -LineNo
    1) [String]
    lsF) (LineNo
    rightLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    -LineNo
    1)
                    in  DiffOperation LineRange
    diffDiffOperation LineRange
    -> [DiffOperation LineRange] -> [DiffOperation LineRange]
    forall a. a -> [a] -> [a]
    : LineNo -> LineNo -> [Diff [String]] -> [DiffOperation LineRange]
    toLineRange(LineNo
    leftLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesF) LineNo
    rightLine [Diff [String]]
    rs
              toChange :: LineNo
    -> LineNo
    -> [String]
    -> [String]
    -> [Diff [String]]
    -> [DiffOperation LineRange]
    toChange LineNo
    leftLine LineNo
    rightLine [String]
    lsF [String]
    lsS [Diff [String]]
    rs=
                    let linesS :: LineNo
    linesS=[String] -> LineNo
    forall a. [a] -> LineNo
    forall (t :: * -> *) a. Foldable t => t a -> LineNo
    length [String]
    lsS
                        linesF :: LineNo
    linesF=[String] -> LineNo
    forall a. [a] -> LineNo
    forall (t :: * -> *) a. Foldable t => t a -> LineNo
    length [String]
    lsF
                    in  LineRange -> LineRange -> DiffOperation LineRange
    forall a. a -> a -> DiffOperation a
    Change ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo
    leftLine,LineNo
    leftLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesFLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    -LineNo
    1) [String]
    lsF) ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo
    rightLine,LineNo
    rightLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesSLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    -LineNo
    1) [String]
    lsS)
                            DiffOperation LineRange
    -> [DiffOperation LineRange] -> [DiffOperation LineRange]
    forall a. a -> [a] -> [a]
    : LineNo -> LineNo -> [Diff [String]] -> [DiffOperation LineRange]
    toLineRange (LineNo
    leftLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesF) (LineNo
    rightLineLineNo -> LineNo -> LineNo
    forall a. Num a => a -> a -> a
    +LineNo
    linesS) [Diff [String]]
    rs

    -- | 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
    ppDiff :: [Diff [String]] -> String
    ppDiff [Diff [String]]
    gdiff =
       let  diffLineRanges :: [DiffOperation LineRange]
    diffLineRanges = [Diff [String]] -> [DiffOperation LineRange]
    diffToLineRanges [Diff [String]]
    gdiff
       in
            Doc -> String
    render ([DiffOperation LineRange] -> Doc
    prettyDiffs [DiffOperation LineRange]
    diffLineRanges) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\n"

    -- | pretty print of diff operations
    prettyDiffs :: [DiffOperation LineRange] -> Doc
    prettyDiffs :: [DiffOperation LineRange] -> Doc
    prettyDiffs [] = Doc
    empty
    prettyDiffs (DiffOperation LineRange
    d : [DiffOperation LineRange]
    rest) = DiffOperation LineRange -> Doc
    prettyDiff DiffOperation LineRange
    d Doc -> Doc -> Doc
    $$ [DiffOperation LineRange] -> Doc
    prettyDiffs [DiffOperation LineRange]
    rest
        where
          prettyDiff :: DiffOperation LineRange -> Doc
    prettyDiff (Deletion LineRange
    inLeft LineNo
    lineNoRight) =
              (LineNo, LineNo) -> Doc
    prettyRange (LineRange -> (LineNo, LineNo)
    lrNumbers LineRange
    inLeft) Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> Char -> Doc
    char Char
    'd' Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> LineNo -> Doc
    int LineNo
    lineNoRight Doc -> Doc -> Doc
    $$
              Char -> [String] -> Doc
    prettyLines Char
    '<' (LineRange -> [String]
    lrContents LineRange
    inLeft)
          prettyDiff (Addition LineRange
    inRight LineNo
    lineNoLeft) =
              LineNo -> Doc
    int LineNo
    lineNoLeft Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> Char -> Doc
    char Char
    'a' Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> (LineNo, LineNo) -> Doc
    prettyRange (LineRange -> (LineNo, LineNo)
    lrNumbers LineRange
    inRight) Doc -> Doc -> Doc
    $$
              Char -> [String] -> Doc
    prettyLines Char
    '>' (LineRange -> [String]
    lrContents LineRange
    inRight)
          prettyDiff (Change LineRange
    inLeft LineRange
    inRight) =
              (LineNo, LineNo) -> Doc
    prettyRange (LineRange -> (LineNo, LineNo)
    lrNumbers LineRange
    inLeft) Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> Char -> Doc
    char Char
    'c' Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> (LineNo, LineNo) -> Doc
    prettyRange (LineRange -> (LineNo, LineNo)
    lrNumbers LineRange
    inRight) Doc -> Doc -> Doc
    $$
              Char -> [String] -> Doc
    prettyLines Char
    '<' (LineRange -> [String]
    lrContents LineRange
    inLeft) Doc -> Doc -> Doc
    $$
              String -> Doc
    text String
    "---" Doc -> Doc -> Doc
    $$
              Char -> [String] -> Doc
    prettyLines Char
    '>' (LineRange -> [String]
    lrContents LineRange
    inRight)
          prettyRange :: (LineNo, LineNo) -> Doc
    prettyRange (LineNo
    start, LineNo
    end) =
              if LineNo
    start LineNo -> LineNo -> Bool
    forall a. Eq a => a -> a -> Bool
    == LineNo
    end then LineNo -> Doc
    int LineNo
    start else LineNo -> Doc
    int LineNo
    start Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> Doc
    comma Doc -> Doc -> Doc
    forall a. Semigroup a => a -> a -> a
    <> LineNo -> Doc
    int LineNo
    end
          prettyLines :: Char -> [String] -> Doc
    prettyLines Char
    start [String]
    lins =
              [Doc] -> Doc
    vcat ((String -> Doc) -> [String] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map (\String
    l -> Char -> Doc
    char Char
    start Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    l) [String]
    lins)

    -- | Parse pretty printed Diffs as DiffOperations
    parsePrettyDiffs :: String -> [DiffOperation LineRange]
    parsePrettyDiffs :: String -> [DiffOperation LineRange]
    parsePrettyDiffs = [DiffOperation LineRange] -> [DiffOperation LineRange]
    forall a. [a] -> [a]
    reverse ([DiffOperation LineRange] -> [DiffOperation LineRange])
    -> (String -> [DiffOperation LineRange])
    -> String
    -> [DiffOperation LineRange]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [DiffOperation LineRange] -> [String] -> [DiffOperation LineRange]
    doParse [] ([String] -> [DiffOperation LineRange])
    -> (String -> [String]) -> String -> [DiffOperation LineRange]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String]
    lines
      where
        doParse :: [DiffOperation LineRange] -> [String] -> [DiffOperation LineRange]
    doParse [DiffOperation LineRange]
    diffs [] = [DiffOperation LineRange]
    diffs
        doParse [DiffOperation LineRange]
    diffs [String]
    s =
            let (Maybe (DiffOperation LineRange)
    mnd,[String]
    r) = [String] -> (Maybe (DiffOperation LineRange), [String])
    parseDiff [String]
    s
            in case Maybe (DiffOperation LineRange)
    mnd of
                Just DiffOperation LineRange
    nd -> [DiffOperation LineRange] -> [String] -> [DiffOperation LineRange]
    doParse (DiffOperation LineRange
    ndDiffOperation LineRange
    -> [DiffOperation LineRange] -> [DiffOperation LineRange]
    forall a. a -> [a] -> [a]
    :[DiffOperation LineRange]
    diffs) [String]
    r
                Maybe (DiffOperation LineRange)
    _          -> [DiffOperation LineRange] -> [String] -> [DiffOperation LineRange]
    doParse [DiffOperation LineRange]
    diffs [String]
    r
        parseDiff :: [String] -> (Maybe (DiffOperation LineRange), [String])
    parseDiff [] = (Maybe (DiffOperation LineRange)
    forall a. Maybe a
    Nothing,[])
        parseDiff (String
    h:[String]
    rs) = let
            ((LineNo, LineNo)
    r1,String
    hrs1) = String -> ((LineNo, LineNo), String)
    parseRange String
    h
            in case String
    hrs1 of
                    (Char
    'd':String
    hrs2) -> (LineNo, LineNo)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    parseDel (LineNo, LineNo)
    r1 String
    hrs2 [String]
    rs
                    (Char
    'a':String
    hrs2) -> (LineNo, LineNo)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    forall {b}.
    (LineNo, b)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    parseAdd (LineNo, LineNo)
    r1 String
    hrs2 [String]
    rs
                    (Char
    'c':String
    hrs2) -> (LineNo, LineNo)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    parseChange (LineNo, LineNo)
    r1 String
    hrs2 [String]
    rs
                    String
    _ -> (Maybe (DiffOperation LineRange)
    forall a. Maybe a
    Nothing,[String]
    rs)
        parseDel :: (LineNo, LineNo)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    parseDel (LineNo, LineNo)
    r1 String
    hrs2 [String]
    rs = let
            ((LineNo, LineNo)
    r2,String
    _) = String -> ((LineNo, LineNo), String)
    parseRange String
    hrs2
            ([String]
    ls,[String]
    rs2) = (String -> Bool) -> [String] -> ([String], [String])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isPrefixOf String
    "<") [String]
    rs
            in (DiffOperation LineRange -> Maybe (DiffOperation LineRange)
    forall a. a -> Maybe a
    Just (DiffOperation LineRange -> Maybe (DiffOperation LineRange))
    -> DiffOperation LineRange -> Maybe (DiffOperation LineRange)
    forall a b. (a -> b) -> a -> b
    $ LineRange -> LineNo -> DiffOperation LineRange
    forall a. a -> LineNo -> DiffOperation a
    Deletion ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo, LineNo)
    r1 ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (LineNo -> String -> String
    forall a. LineNo -> [a] -> [a]
    drop LineNo
    2) [String]
    ls)) ((LineNo, LineNo) -> LineNo
    forall a b. (a, b) -> a
    fst (LineNo, LineNo)
    r2), [String]
    rs2)
        parseAdd :: (LineNo, b)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    parseAdd (LineNo, b)
    r1 String
    hrs2 [String]
    rs = let
            ((LineNo, LineNo)
    r2,String
    _) = String -> ((LineNo, LineNo), String)
    parseRange String
    hrs2
            ([String]
    ls,[String]
    rs2) = (String -> Bool) -> [String] -> ([String], [String])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isPrefixOf String
    ">") [String]
    rs
            in (DiffOperation LineRange -> Maybe (DiffOperation LineRange)
    forall a. a -> Maybe a
    Just (DiffOperation LineRange -> Maybe (DiffOperation LineRange))
    -> DiffOperation LineRange -> Maybe (DiffOperation LineRange)
    forall a b. (a -> b) -> a -> b
    $ LineRange -> LineNo -> DiffOperation LineRange
    forall a. a -> LineNo -> DiffOperation a
    Addition ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo, LineNo)
    r2 ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (LineNo -> String -> String
    forall a. LineNo -> [a] -> [a]
    drop LineNo
    2) [String]
    ls)) ((LineNo, b) -> LineNo
    forall a b. (a, b) -> a
    fst (LineNo, b)
    r1), [String]
    rs2)
        parseChange :: (LineNo, LineNo)
    -> String
    -> [String]
    -> (Maybe (DiffOperation LineRange), [String])
    parseChange (LineNo, LineNo)
    r1 String
    hrs2 [String]
    rs = let
            ((LineNo, LineNo)
    r2,String
    _) = String -> ((LineNo, LineNo), String)
    parseRange String
    hrs2
            ([String]
    ls1,[String]
    rs2) = (String -> Bool) -> [String] -> ([String], [String])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isPrefixOf String
    "<") [String]
    rs
            in case [String]
    rs2 of
                (String
    "---":[String]
    rs3) -> let
                    ([String]
    ls2,[String]
    rs4) = (String -> Bool) -> [String] -> ([String], [String])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isPrefixOf String
    ">") [String]
    rs3
                    in (DiffOperation LineRange -> Maybe (DiffOperation LineRange)
    forall a. a -> Maybe a
    Just (DiffOperation LineRange -> Maybe (DiffOperation LineRange))
    -> DiffOperation LineRange -> Maybe (DiffOperation LineRange)
    forall a b. (a -> b) -> a -> b
    $ LineRange -> LineRange -> DiffOperation LineRange
    forall a. a -> a -> DiffOperation a
    Change ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo, LineNo)
    r1 ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (LineNo -> String -> String
    forall a. LineNo -> [a] -> [a]
    drop LineNo
    2) [String]
    ls1)) ((LineNo, LineNo) -> [String] -> LineRange
    LineRange (LineNo, LineNo)
    r2 ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (LineNo -> String -> String
    forall a. LineNo -> [a] -> [a]
    drop LineNo
    2) [String]
    ls2)), [String]
    rs4)
                [String]
    _ -> (Maybe (DiffOperation LineRange)
    forall a. Maybe a
    Nothing,[String]
    rs2)
        parseRange :: String -> ((LineNo, LineNo),String)
        parseRange :: String -> ((LineNo, LineNo), String)
    parseRange String
    l = let
            (String
    fstLine,String
    rs) = (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span Char -> Bool
    isDigit String
    l
            (String
    sndLine,String
    rs3) = case String
    rs of
                                        (Char
    ',':String
    rs2) -> (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span Char -> Bool
    isDigit String
    rs2
                                        String
    _ -> (String
    fstLine,String
    rs)
            in ((String -> LineNo
    forall a. Read a => String -> a
    read String
    fstLine,String -> LineNo
    forall a. Read a => String -> a
    read String
    sndLine),String
    rs3)

    -- | Line number alias
    type LineNo = Int

    -- | Line Range: start, end and contents
    data LineRange = LineRange { LineRange -> (LineNo, LineNo)
    lrNumbers :: (LineNo, LineNo)
                               , LineRange -> [String]
    lrContents :: [String]
                               }
                deriving (LineNo -> LineRange -> String -> String
    [LineRange] -> String -> String
    LineRange -> String
    (LineNo -> LineRange -> String -> String)
    -> (LineRange -> String)
    -> ([LineRange] -> String -> String)
    -> Show LineRange
    forall a.
    (LineNo -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: LineNo -> LineRange -> String -> String
    showsPrec :: LineNo -> LineRange -> String -> String
    $cshow :: LineRange -> String
    show :: LineRange -> String
    $cshowList :: [LineRange] -> String -> String
    showList :: [LineRange] -> String -> String
    Show,ReadPrec [LineRange]
    ReadPrec LineRange
    LineNo -> ReadS LineRange
    ReadS [LineRange]
    (LineNo -> ReadS LineRange)
    -> ReadS [LineRange]
    -> ReadPrec LineRange
    -> ReadPrec [LineRange]
    -> Read LineRange
    forall a.
    (LineNo -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: LineNo -> ReadS LineRange
    readsPrec :: LineNo -> ReadS LineRange
    $creadList :: ReadS [LineRange]
    readList :: ReadS [LineRange]
    $creadPrec :: ReadPrec LineRange
    readPrec :: ReadPrec LineRange
    $creadListPrec :: ReadPrec [LineRange]
    readListPrec :: ReadPrec [LineRange]
    Read,LineRange -> LineRange -> Bool
    (LineRange -> LineRange -> Bool)
    -> (LineRange -> LineRange -> Bool) -> Eq LineRange
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: LineRange -> LineRange -> Bool
    == :: LineRange -> LineRange -> Bool
    $c/= :: LineRange -> LineRange -> Bool
    /= :: LineRange -> LineRange -> Bool
    Eq,Eq LineRange
    Eq LineRange =>
    (LineRange -> LineRange -> Ordering)
    -> (LineRange -> LineRange -> Bool)
    -> (LineRange -> LineRange -> Bool)
    -> (LineRange -> LineRange -> Bool)
    -> (LineRange -> LineRange -> Bool)
    -> (LineRange -> LineRange -> LineRange)
    -> (LineRange -> LineRange -> LineRange)
    -> Ord LineRange
    LineRange -> LineRange -> Bool
    LineRange -> LineRange -> Ordering
    LineRange -> LineRange -> LineRange
    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
    $ccompare :: LineRange -> LineRange -> Ordering
    compare :: LineRange -> LineRange -> Ordering
    $c< :: LineRange -> LineRange -> Bool
    < :: LineRange -> LineRange -> Bool
    $c<= :: LineRange -> LineRange -> Bool
    <= :: LineRange -> LineRange -> Bool
    $c> :: LineRange -> LineRange -> Bool
    > :: LineRange -> LineRange -> Bool
    $c>= :: LineRange -> LineRange -> Bool
    >= :: LineRange -> LineRange -> Bool
    $cmax :: LineRange -> LineRange -> LineRange
    max :: LineRange -> LineRange -> LineRange
    $cmin :: LineRange -> LineRange -> LineRange
    min :: LineRange -> LineRange -> LineRange
    Ord)

    -- | Diff Operation  representing changes to apply
    data DiffOperation a = Deletion a LineNo
                | Addition a LineNo
                | Change a a
                deriving (LineNo -> DiffOperation a -> String -> String
    [DiffOperation a] -> String -> String
    DiffOperation a -> String
    (LineNo -> DiffOperation a -> String -> String)
    -> (DiffOperation a -> String)
    -> ([DiffOperation a] -> String -> String)
    -> Show (DiffOperation a)
    forall a. Show a => LineNo -> DiffOperation a -> String -> String
    forall a. Show a => [DiffOperation a] -> String -> String
    forall a. Show a => DiffOperation a -> String
    forall a.
    (LineNo -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: forall a. Show a => LineNo -> DiffOperation a -> String -> String
    showsPrec :: LineNo -> DiffOperation a -> String -> String
    $cshow :: forall a. Show a => DiffOperation a -> String
    show :: DiffOperation a -> String
    $cshowList :: forall a. Show a => [DiffOperation a] -> String -> String
    showList :: [DiffOperation a] -> String -> String
    Show,ReadPrec [DiffOperation a]
    ReadPrec (DiffOperation a)
    LineNo -> ReadS (DiffOperation a)
    ReadS [DiffOperation a]
    (LineNo -> ReadS (DiffOperation a))
    -> ReadS [DiffOperation a]
    -> ReadPrec (DiffOperation a)
    -> ReadPrec [DiffOperation a]
    -> Read (DiffOperation a)
    forall a. Read a => ReadPrec [DiffOperation a]
    forall a. Read a => ReadPrec (DiffOperation a)
    forall a. Read a => LineNo -> ReadS (DiffOperation a)
    forall a. Read a => ReadS [DiffOperation a]
    forall a.
    (LineNo -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: forall a. Read a => LineNo -> ReadS (DiffOperation a)
    readsPrec :: LineNo -> ReadS (DiffOperation a)
    $creadList :: forall a. Read a => ReadS [DiffOperation a]
    readList :: ReadS [DiffOperation a]
    $creadPrec :: forall a. Read a => ReadPrec (DiffOperation a)
    readPrec :: ReadPrec (DiffOperation a)
    $creadListPrec :: forall a. Read a => ReadPrec [DiffOperation a]
    readListPrec :: ReadPrec [DiffOperation a]
    Read,DiffOperation a -> DiffOperation a -> Bool
    (DiffOperation a -> DiffOperation a -> Bool)
    -> (DiffOperation a -> DiffOperation a -> Bool)
    -> Eq (DiffOperation a)
    forall a. Eq a => DiffOperation a -> DiffOperation a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => DiffOperation a -> DiffOperation a -> Bool
    == :: DiffOperation a -> DiffOperation a -> Bool
    $c/= :: forall a. Eq a => DiffOperation a -> DiffOperation a -> Bool
    /= :: DiffOperation a -> DiffOperation a -> Bool
    Eq,Eq (DiffOperation a)
    Eq (DiffOperation a) =>
    (DiffOperation a -> DiffOperation a -> Ordering)
    -> (DiffOperation a -> DiffOperation a -> Bool)
    -> (DiffOperation a -> DiffOperation a -> Bool)
    -> (DiffOperation a -> DiffOperation a -> Bool)
    -> (DiffOperation a -> DiffOperation a -> Bool)
    -> (DiffOperation a -> DiffOperation a -> DiffOperation a)
    -> (DiffOperation a -> DiffOperation a -> DiffOperation a)
    -> Ord (DiffOperation a)
    DiffOperation a -> DiffOperation a -> Bool
    DiffOperation a -> DiffOperation a -> Ordering
    DiffOperation a -> DiffOperation a -> DiffOperation 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 (DiffOperation a)
    forall a. Ord a => DiffOperation a -> DiffOperation a -> Bool
    forall a. Ord a => DiffOperation a -> DiffOperation a -> Ordering
    forall a.
    Ord a =>
    DiffOperation a -> DiffOperation a -> DiffOperation a
    $ccompare :: forall a. Ord a => DiffOperation a -> DiffOperation a -> Ordering
    compare :: DiffOperation a -> DiffOperation a -> Ordering
    $c< :: forall a. Ord a => DiffOperation a -> DiffOperation a -> Bool
    < :: DiffOperation a -> DiffOperation a -> Bool
    $c<= :: forall a. Ord a => DiffOperation a -> DiffOperation a -> Bool
    <= :: DiffOperation a -> DiffOperation a -> Bool
    $c> :: forall a. Ord a => DiffOperation a -> DiffOperation a -> Bool
    > :: DiffOperation a -> DiffOperation a -> Bool
    $c>= :: forall a. Ord a => DiffOperation a -> DiffOperation a -> Bool
    >= :: DiffOperation a -> DiffOperation a -> Bool
    $cmax :: forall a.
    Ord a =>
    DiffOperation a -> DiffOperation a -> DiffOperation a
    max :: DiffOperation a -> DiffOperation a -> DiffOperation a
    $cmin :: forall a.
    Ord a =>
    DiffOperation a -> DiffOperation a -> DiffOperation a
    min :: DiffOperation a -> DiffOperation a -> DiffOperation a
    Ord)