{-# OPTIONS_HADDOCK not-home #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE PatternGuards #-} module Hedgehog.Internal.Show ( Name , Value(..) , ValueDiff(..) , LineDiff(..) , mkValue , showPretty , valueDiff , lineDiff , toLineDiff , renderValue , renderValueDiff , renderLineDiff , takeLeft , takeRight ) where import Data.Bifunctor (second) import Text.Show.Pretty (Value(..), Name, reify, valToStr, ppShow) data ValueDiff = ValueCon Name [ValueDiff] | ValueRec Name [(Name, ValueDiff)] | ValueTuple [ValueDiff] | ValueList [ValueDiff] | ValueSame Value | ValueDiff Value Value deriving (ValueDiff -> ValueDiff -> Bool (ValueDiff -> ValueDiff -> Bool) -> (ValueDiff -> ValueDiff -> Bool) -> Eq ValueDiff forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: ValueDiff -> ValueDiff -> Bool == :: ValueDiff -> ValueDiff -> Bool $c/= :: ValueDiff -> ValueDiff -> Bool /= :: ValueDiff -> ValueDiff -> Bool Eq, Int -> ValueDiff -> ShowS [ValueDiff] -> ShowS ValueDiff -> Name (Int -> ValueDiff -> ShowS) -> (ValueDiff -> Name) -> ([ValueDiff] -> ShowS) -> Show ValueDiff forall a. (Int -> a -> ShowS) -> (a -> Name) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> ValueDiff -> ShowS showsPrec :: Int -> ValueDiff -> ShowS $cshow :: ValueDiff -> Name show :: ValueDiff -> Name $cshowList :: [ValueDiff] -> ShowS showList :: [ValueDiff] -> ShowS Show) data LineDiff = LineSame String | LineRemoved String | LineAdded String deriving (LineDiff -> LineDiff -> Bool (LineDiff -> LineDiff -> Bool) -> (LineDiff -> LineDiff -> Bool) -> Eq LineDiff forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: LineDiff -> LineDiff -> Bool == :: LineDiff -> LineDiff -> Bool $c/= :: LineDiff -> LineDiff -> Bool /= :: LineDiff -> LineDiff -> Bool Eq, Int -> LineDiff -> ShowS [LineDiff] -> ShowS LineDiff -> Name (Int -> LineDiff -> ShowS) -> (LineDiff -> Name) -> ([LineDiff] -> ShowS) -> Show LineDiff forall a. (Int -> a -> ShowS) -> (a -> Name) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> LineDiff -> ShowS showsPrec :: Int -> LineDiff -> ShowS $cshow :: LineDiff -> Name show :: LineDiff -> Name $cshowList :: [LineDiff] -> ShowS showList :: [LineDiff] -> ShowS Show) data DocDiff = DocSame Int String | DocRemoved Int String | DocAdded Int String | DocOpen Int String | DocItem Int String [DocDiff] | DocClose Int String deriving (DocDiff -> DocDiff -> Bool (DocDiff -> DocDiff -> Bool) -> (DocDiff -> DocDiff -> Bool) -> Eq DocDiff forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: DocDiff -> DocDiff -> Bool == :: DocDiff -> DocDiff -> Bool $c/= :: DocDiff -> DocDiff -> Bool /= :: DocDiff -> DocDiff -> Bool Eq, Int -> DocDiff -> ShowS [DocDiff] -> ShowS DocDiff -> Name (Int -> DocDiff -> ShowS) -> (DocDiff -> Name) -> ([DocDiff] -> ShowS) -> Show DocDiff forall a. (Int -> a -> ShowS) -> (a -> Name) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> DocDiff -> ShowS showsPrec :: Int -> DocDiff -> ShowS $cshow :: DocDiff -> Name show :: DocDiff -> Name $cshowList :: [DocDiff] -> ShowS showList :: [DocDiff] -> ShowS Show) renderValue :: Value -> String renderValue :: Value -> Name renderValue = Value -> Name valToStr renderValueDiff :: ValueDiff -> String renderValueDiff :: ValueDiff -> Name renderValueDiff = [Name] -> Name unlines ([Name] -> Name) -> (ValueDiff -> [Name]) -> ValueDiff -> Name forall b c a. (b -> c) -> (a -> b) -> a -> c . (LineDiff -> Name) -> [LineDiff] -> [Name] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap LineDiff -> Name renderLineDiff ([LineDiff] -> [Name]) -> (ValueDiff -> [LineDiff]) -> ValueDiff -> [Name] forall b c a. (b -> c) -> (a -> b) -> a -> c . ValueDiff -> [LineDiff] toLineDiff renderLineDiff :: LineDiff -> String renderLineDiff :: LineDiff -> Name renderLineDiff = \case LineSame Name x -> Name " " Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x LineRemoved Name x -> Name "- " Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x LineAdded Name x -> Name "+ " Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x mkValue :: Show a => a -> Maybe Value mkValue :: forall a. Show a => a -> Maybe Value mkValue = a -> Maybe Value forall a. Show a => a -> Maybe Value reify showPretty :: Show a => a -> String showPretty :: forall a. Show a => a -> Name showPretty = a -> Name forall a. Show a => a -> Name ppShow lineDiff :: Value -> Value -> [LineDiff] lineDiff :: Value -> Value -> [LineDiff] lineDiff Value x Value y = ValueDiff -> [LineDiff] toLineDiff (ValueDiff -> [LineDiff]) -> ValueDiff -> [LineDiff] forall a b. (a -> b) -> a -> b $ Value -> Value -> ValueDiff valueDiff Value x Value y toLineDiff :: ValueDiff -> [LineDiff] toLineDiff :: ValueDiff -> [LineDiff] toLineDiff = (DocDiff -> [LineDiff]) -> [DocDiff] -> [LineDiff] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap (Int -> Name -> DocDiff -> [LineDiff] mkLineDiff Int 0 Name "") ([DocDiff] -> [LineDiff]) -> (ValueDiff -> [DocDiff]) -> ValueDiff -> [LineDiff] forall b c a. (b -> c) -> (a -> b) -> a -> c . [DocDiff] -> [DocDiff] collapseOpen ([DocDiff] -> [DocDiff]) -> (ValueDiff -> [DocDiff]) -> ValueDiff -> [DocDiff] forall b c a. (b -> c) -> (a -> b) -> a -> c . [DocDiff] -> [DocDiff] dropLeadingSep ([DocDiff] -> [DocDiff]) -> (ValueDiff -> [DocDiff]) -> ValueDiff -> [DocDiff] forall b c a. (b -> c) -> (a -> b) -> a -> c . Int -> ValueDiff -> [DocDiff] mkDocDiff Int 0 valueDiff :: Value -> Value -> ValueDiff valueDiff :: Value -> Value -> ValueDiff valueDiff Value x Value y = if Value x Value -> Value -> Bool forall a. Eq a => a -> a -> Bool == Value y then Value -> ValueDiff ValueSame Value x else case (Value x, Value y) of (Con Name nx [Value] xs, Con Name ny [Value] ys) | Name nx Name -> Name -> Bool forall a. Eq a => a -> a -> Bool == Name ny , [Value] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Value] xs Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == [Value] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Value] ys -> Name -> [ValueDiff] -> ValueDiff ValueCon Name nx ((Value -> Value -> ValueDiff) -> [Value] -> [Value] -> [ValueDiff] forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] zipWith Value -> Value -> ValueDiff valueDiff [Value] xs [Value] ys) (Rec Name nx [(Name, Value)] nxs, Rec Name ny [(Name, Value)] nys) | Name nx Name -> Name -> Bool forall a. Eq a => a -> a -> Bool == Name ny , ((Name, Value) -> Name) -> [(Name, Value)] -> [Name] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Name, Value) -> Name forall a b. (a, b) -> a fst [(Name, Value)] nxs [Name] -> [Name] -> Bool forall a. Eq a => a -> a -> Bool == ((Name, Value) -> Name) -> [(Name, Value)] -> [Name] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Name, Value) -> Name forall a b. (a, b) -> a fst [(Name, Value)] nys , [Name] ns <- ((Name, Value) -> Name) -> [(Name, Value)] -> [Name] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Name, Value) -> Name forall a b. (a, b) -> a fst [(Name, Value)] nxs , [Value] xs <- ((Name, Value) -> Value) -> [(Name, Value)] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Name, Value) -> Value forall a b. (a, b) -> b snd [(Name, Value)] nxs , [Value] ys <- ((Name, Value) -> Value) -> [(Name, Value)] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Name, Value) -> Value forall a b. (a, b) -> b snd [(Name, Value)] nys -> Name -> [(Name, ValueDiff)] -> ValueDiff ValueRec Name nx ([Name] -> [ValueDiff] -> [(Name, ValueDiff)] forall a b. [a] -> [b] -> [(a, b)] zip [Name] ns ((Value -> Value -> ValueDiff) -> [Value] -> [Value] -> [ValueDiff] forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] zipWith Value -> Value -> ValueDiff valueDiff [Value] xs [Value] ys)) (Tuple [Value] xs, Tuple [Value] ys) | [Value] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Value] xs Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == [Value] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Value] ys -> [ValueDiff] -> ValueDiff ValueTuple ((Value -> Value -> ValueDiff) -> [Value] -> [Value] -> [ValueDiff] forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] zipWith Value -> Value -> ValueDiff valueDiff [Value] xs [Value] ys) (List [Value] xs, List [Value] ys) | [Value] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Value] xs Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == [Value] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Value] ys -> [ValueDiff] -> ValueDiff ValueList ((Value -> Value -> ValueDiff) -> [Value] -> [Value] -> [ValueDiff] forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] zipWith Value -> Value -> ValueDiff valueDiff [Value] xs [Value] ys) (Value, Value) _ -> Value -> Value -> ValueDiff ValueDiff Value x Value y takeLeft :: ValueDiff -> Value takeLeft :: ValueDiff -> Value takeLeft = \case ValueCon Name n [ValueDiff] xs -> Name -> [Value] -> Value Con Name n ((ValueDiff -> Value) -> [ValueDiff] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ValueDiff -> Value takeLeft [ValueDiff] xs) ValueRec Name n [(Name, ValueDiff)] nxs -> Name -> [(Name, Value)] -> Value Rec Name n (((Name, ValueDiff) -> (Name, Value)) -> [(Name, ValueDiff)] -> [(Name, Value)] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ((ValueDiff -> Value) -> (Name, ValueDiff) -> (Name, Value) forall b c a. (b -> c) -> (a, b) -> (a, c) forall (p :: * -> * -> *) b c a. Bifunctor p => (b -> c) -> p a b -> p a c second ValueDiff -> Value takeLeft) [(Name, ValueDiff)] nxs) ValueTuple [ValueDiff] xs -> [Value] -> Value Tuple ((ValueDiff -> Value) -> [ValueDiff] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ValueDiff -> Value takeLeft [ValueDiff] xs) ValueList [ValueDiff] xs -> [Value] -> Value List ((ValueDiff -> Value) -> [ValueDiff] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ValueDiff -> Value takeLeft [ValueDiff] xs) ValueSame Value x -> Value x ValueDiff Value x Value _ -> Value x takeRight :: ValueDiff -> Value takeRight :: ValueDiff -> Value takeRight = \case ValueCon Name n [ValueDiff] xs -> Name -> [Value] -> Value Con Name n ((ValueDiff -> Value) -> [ValueDiff] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ValueDiff -> Value takeRight [ValueDiff] xs) ValueRec Name n [(Name, ValueDiff)] nxs -> Name -> [(Name, Value)] -> Value Rec Name n (((Name, ValueDiff) -> (Name, Value)) -> [(Name, ValueDiff)] -> [(Name, Value)] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ((ValueDiff -> Value) -> (Name, ValueDiff) -> (Name, Value) forall b c a. (b -> c) -> (a, b) -> (a, c) forall (p :: * -> * -> *) b c a. Bifunctor p => (b -> c) -> p a b -> p a c second ValueDiff -> Value takeRight) [(Name, ValueDiff)] nxs) ValueTuple [ValueDiff] xs -> [Value] -> Value Tuple ((ValueDiff -> Value) -> [ValueDiff] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ValueDiff -> Value takeRight [ValueDiff] xs) ValueList [ValueDiff] xs -> [Value] -> Value List ((ValueDiff -> Value) -> [ValueDiff] -> [Value] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap ValueDiff -> Value takeRight [ValueDiff] xs) ValueSame Value x -> Value x ValueDiff Value _ Value x -> Value x mkLineDiff :: Int -> String -> DocDiff -> [LineDiff] mkLineDiff :: Int -> Name -> DocDiff -> [LineDiff] mkLineDiff Int indent0 Name prefix0 DocDiff diff = let mkLinePrefix :: Int -> Name mkLinePrefix Int indent = Int -> Name spaces Int indent0 Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name prefix0 Name -> ShowS forall a. [a] -> [a] -> [a] ++ Int -> Name spaces Int indent mkLineIndent :: Int -> Int mkLineIndent Int indent = Int indent0 Int -> Int -> Int forall a. Num a => a -> a -> a + Name -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length Name prefix0 Int -> Int -> Int forall a. Num a => a -> a -> a + Int indent in case DocDiff diff of DocSame Int indent Name x -> [Name -> LineDiff LineSame (Name -> LineDiff) -> Name -> LineDiff forall a b. (a -> b) -> a -> b $ Int -> Name mkLinePrefix Int indent Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x] DocRemoved Int indent Name x -> [Name -> LineDiff LineRemoved (Name -> LineDiff) -> Name -> LineDiff forall a b. (a -> b) -> a -> b $ Int -> Name mkLinePrefix Int indent Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x] DocAdded Int indent Name x -> [Name -> LineDiff LineAdded (Name -> LineDiff) -> Name -> LineDiff forall a b. (a -> b) -> a -> b $ Int -> Name mkLinePrefix Int indent Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x] DocOpen Int indent Name x -> [Name -> LineDiff LineSame (Name -> LineDiff) -> Name -> LineDiff forall a b. (a -> b) -> a -> b $ Int -> Name mkLinePrefix Int indent Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x] DocItem Int _ Name _ [] -> [] DocItem Int indent Name prefix (x :: DocDiff x@DocRemoved{} : y :: DocDiff y@DocAdded{} : [DocDiff] xs) -> Int -> Name -> DocDiff -> [LineDiff] mkLineDiff (Int -> Int mkLineIndent Int indent) Name prefix DocDiff x [LineDiff] -> [LineDiff] -> [LineDiff] forall a. [a] -> [a] -> [a] ++ Int -> Name -> DocDiff -> [LineDiff] mkLineDiff (Int -> Int mkLineIndent Int indent) Name prefix DocDiff y [LineDiff] -> [LineDiff] -> [LineDiff] forall a. [a] -> [a] -> [a] ++ (DocDiff -> [LineDiff]) -> [DocDiff] -> [LineDiff] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap (Int -> Name -> DocDiff -> [LineDiff] mkLineDiff (Int -> Int mkLineIndent (Int indent Int -> Int -> Int forall a. Num a => a -> a -> a + Name -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length Name prefix)) Name "") [DocDiff] xs DocItem Int indent Name prefix (DocDiff x : [DocDiff] xs) -> Int -> Name -> DocDiff -> [LineDiff] mkLineDiff (Int -> Int mkLineIndent Int indent) Name prefix DocDiff x [LineDiff] -> [LineDiff] -> [LineDiff] forall a. [a] -> [a] -> [a] ++ (DocDiff -> [LineDiff]) -> [DocDiff] -> [LineDiff] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap (Int -> Name -> DocDiff -> [LineDiff] mkLineDiff (Int -> Int mkLineIndent (Int indent Int -> Int -> Int forall a. Num a => a -> a -> a + Name -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length Name prefix)) Name "") [DocDiff] xs DocClose Int indent Name x -> [Name -> LineDiff LineSame (Name -> LineDiff) -> Name -> LineDiff forall a b. (a -> b) -> a -> b $ Int -> Name spaces (Int -> Int mkLineIndent Int indent) Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name x] spaces :: Int -> String spaces :: Int -> Name spaces Int indent = Int -> Char -> Name forall a. Int -> a -> [a] replicate Int indent Char ' ' collapseOpen :: [DocDiff] -> [DocDiff] collapseOpen :: [DocDiff] -> [DocDiff] collapseOpen = \case DocSame Int indent Name line : DocOpen Int _ Name bra : [DocDiff] xs -> Int -> Name -> DocDiff DocSame Int indent (Name line Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name " " Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name bra) DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : [DocDiff] -> [DocDiff] collapseOpen [DocDiff] xs DocItem Int indent Name prefix [DocDiff] xs : [DocDiff] ys -> Int -> Name -> [DocDiff] -> DocDiff DocItem Int indent Name prefix ([DocDiff] -> [DocDiff] collapseOpen [DocDiff] xs) DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : [DocDiff] -> [DocDiff] collapseOpen [DocDiff] ys DocDiff x : [DocDiff] xs -> DocDiff x DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : [DocDiff] -> [DocDiff] collapseOpen [DocDiff] xs [] -> [] dropLeadingSep :: [DocDiff] -> [DocDiff] dropLeadingSep :: [DocDiff] -> [DocDiff] dropLeadingSep = \case DocOpen Int oindent Name bra : DocItem Int indent Name prefix [DocDiff] xs : [DocDiff] ys -> Int -> Name -> DocDiff DocOpen Int oindent Name bra DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : Int -> Name -> [DocDiff] -> DocDiff DocItem (Int indent Int -> Int -> Int forall a. Num a => a -> a -> a + Name -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length Name prefix) Name "" ([DocDiff] -> [DocDiff] dropLeadingSep [DocDiff] xs) DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : [DocDiff] -> [DocDiff] dropLeadingSep [DocDiff] ys DocItem Int indent Name prefix [DocDiff] xs : [DocDiff] ys -> Int -> Name -> [DocDiff] -> DocDiff DocItem Int indent Name prefix ([DocDiff] -> [DocDiff] dropLeadingSep [DocDiff] xs) DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : [DocDiff] -> [DocDiff] dropLeadingSep [DocDiff] ys DocDiff x : [DocDiff] xs -> DocDiff x DocDiff -> [DocDiff] -> [DocDiff] forall a. a -> [a] -> [a] : [DocDiff] -> [DocDiff] dropLeadingSep [DocDiff] xs [] -> [] mkDocDiff :: Int -> ValueDiff -> [DocDiff] mkDocDiff :: Int -> ValueDiff -> [DocDiff] mkDocDiff Int indent = \case ValueSame Value x -> Int -> Name -> [DocDiff] same Int indent (Value -> Name renderValue Value x) ValueDiff diff | Value x <- ValueDiff -> Value takeLeft ValueDiff diff , Value y <- ValueDiff -> Value takeRight ValueDiff diff , Value -> Bool oneLiner Value x , Value -> Bool oneLiner Value y -> Int -> Name -> [DocDiff] removed Int indent (Value -> Name renderValue Value x) [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ Int -> Name -> [DocDiff] added Int indent (Value -> Name renderValue Value y) ValueCon Name n [ValueDiff] xs -> Int -> Name -> [DocDiff] same Int indent Name n [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ (ValueDiff -> [DocDiff]) -> [ValueDiff] -> [DocDiff] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap (Int -> ValueDiff -> [DocDiff] mkDocDiff (Int indent Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)) [ValueDiff] xs ValueRec Name n [(Name, ValueDiff)] nxs -> Int -> Name -> [DocDiff] same Int indent Name n [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ [Int -> Name -> DocDiff DocOpen Int indent Name "{"] [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ ((Name, ValueDiff) -> DocDiff) -> [(Name, ValueDiff)] -> [DocDiff] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (\(Name name, ValueDiff x) -> Int -> Name -> [DocDiff] -> DocDiff DocItem (Int indent Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2) Name ", " (Int -> Name -> [DocDiff] same Int 0 (Name name Name -> ShowS forall a. [a] -> [a] -> [a] ++ Name " =") [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ Int -> ValueDiff -> [DocDiff] mkDocDiff Int 2 ValueDiff x)) [(Name, ValueDiff)] nxs [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ [Int -> Name -> DocDiff DocClose (Int indent Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2) Name "}"] ValueTuple [ValueDiff] xs -> [Int -> Name -> DocDiff DocOpen Int indent Name "("] [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ (ValueDiff -> DocDiff) -> [ValueDiff] -> [DocDiff] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Int -> Name -> [DocDiff] -> DocDiff DocItem Int indent Name ", " ([DocDiff] -> DocDiff) -> (ValueDiff -> [DocDiff]) -> ValueDiff -> DocDiff forall b c a. (b -> c) -> (a -> b) -> a -> c . Int -> ValueDiff -> [DocDiff] mkDocDiff Int 0) [ValueDiff] xs [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ [Int -> Name -> DocDiff DocClose Int indent Name ")"] ValueList [ValueDiff] xs -> [Int -> Name -> DocDiff DocOpen Int indent Name "["] [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ (ValueDiff -> DocDiff) -> [ValueDiff] -> [DocDiff] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Int -> Name -> [DocDiff] -> DocDiff DocItem Int indent Name ", " ([DocDiff] -> DocDiff) -> (ValueDiff -> [DocDiff]) -> ValueDiff -> DocDiff forall b c a. (b -> c) -> (a -> b) -> a -> c . Int -> ValueDiff -> [DocDiff] mkDocDiff Int 0) [ValueDiff] xs [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ [Int -> Name -> DocDiff DocClose Int indent Name "]"] ValueDiff Value x Value y -> Int -> Name -> [DocDiff] removed Int indent (Value -> Name renderValue Value x) [DocDiff] -> [DocDiff] -> [DocDiff] forall a. [a] -> [a] -> [a] ++ Int -> Name -> [DocDiff] added Int indent (Value -> Name renderValue Value y) oneLiner :: Value -> Bool oneLiner :: Value -> Bool oneLiner Value x = case Name -> [Name] lines (Value -> Name renderValue Value x) of Name _ : Name _ : [Name] _ -> Bool False [Name] _ -> Bool True same :: Int -> String -> [DocDiff] same :: Int -> Name -> [DocDiff] same Int indent = (Name -> DocDiff) -> [Name] -> [DocDiff] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Int -> Name -> DocDiff DocSame Int indent) ([Name] -> [DocDiff]) -> (Name -> [Name]) -> Name -> [DocDiff] forall b c a. (b -> c) -> (a -> b) -> a -> c . Name -> [Name] lines removed :: Int -> String -> [DocDiff] removed :: Int -> Name -> [DocDiff] removed Int indent = (Name -> DocDiff) -> [Name] -> [DocDiff] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Int -> Name -> DocDiff DocRemoved Int indent) ([Name] -> [DocDiff]) -> (Name -> [Name]) -> Name -> [DocDiff] forall b c a. (b -> c) -> (a -> b) -> a -> c . Name -> [Name] lines added :: Int -> String -> [DocDiff] added :: Int -> Name -> [DocDiff] added Int indent = (Name -> DocDiff) -> [Name] -> [DocDiff] forall a b. (a -> b) -> [a] -> [b] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Int -> Name -> DocDiff DocAdded Int indent) ([Name] -> [DocDiff]) -> (Name -> [Name]) -> Name -> [DocDiff] forall b c a. (b -> c) -> (a -> b) -> a -> c . Name -> [Name] lines