{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE TypeApplications  #-}
{-# LANGUAGE ViewPatterns      #-}

{-| This module provides functionality for concisely displaying the difference
    between two expressions

    For example, this is used in type errors to explain why the actual type does
    not match the expected type
-}

module Dhall.Diff (
    -- * Diff
      Diff (..)
    , diffNormalized
    , diff
    ) where

import Data.ByteString       (ByteString)
import Data.Foldable         (fold, toList)
import Data.List.NonEmpty    (NonEmpty (..))
import Data.Monoid           (Any (..))
import Data.Sequence         (Seq)
import Data.String           (IsString (..))
import Data.Text             (Text)
import Data.Void             (Void)
import Dhall.Map             (Map)
import Dhall.Pretty.Internal (Ann)
import Dhall.Syntax
    ( Binding (..)
    , Chunks (..)
    , Const (..)
    , DhallDouble (..)
    , Expr (..)
    , FunctionBinding (..)
    , RecordField (..)
    , Var (..)
    , WithComponent (..)
    )
import Numeric.Natural       (Natural)
import Prettyprinter         (Doc, Pretty)

import qualified Data.Algorithm.Diff    as Algo.Diff
import qualified Data.List.NonEmpty
import qualified Data.Set
import qualified Data.Text
import qualified Data.Time              as Time
import qualified Dhall.Map
import qualified Dhall.Normalize        as Normalize
import qualified Dhall.Pretty.Internal  as Internal
import qualified Dhall.Syntax           as Syntax
import qualified Prettyprinter          as Pretty

{-| This type is a `Doc` enriched with a `same` flag to efficiently track if
    any difference was detected
-}
data Diff =
    Diff
        { Diff -> Bool
same :: Bool
        , Diff -> Doc Ann
doc  :: Doc Ann
        }

instance Semigroup Diff where
    Diff Bool
sameL Doc Ann
docL <> :: Diff -> Diff -> Diff
<> Diff Bool
sameR Doc Ann
docR = Bool -> Doc Ann -> Diff
Diff (Bool
sameL Bool -> Bool -> Bool
&& Bool
sameR) (Doc Ann
docL forall a. Semigroup a => a -> a -> a
<> Doc Ann
docR)

instance Monoid (Diff) where
    mempty :: Diff
mempty = Diff {Bool
Doc Ann
doc :: Doc Ann
same :: Bool
doc :: Doc Ann
same :: Bool
..}
      where
        same :: Bool
same = Bool
True

        doc :: Doc Ann
doc = forall a. Monoid a => a
mempty

instance IsString (Diff) where
    fromString :: String -> Diff
fromString String
string = Diff {Bool
Doc Ann
doc :: Doc Ann
same :: Bool
doc :: Doc Ann
same :: Bool
..}
      where
        same :: Bool
same = Bool
True

        doc :: Doc Ann
doc = forall a. IsString a => String -> a
fromString String
string

ignore :: Diff
ignore :: Diff
ignore = Diff
"…"

align :: Diff -> Diff
align :: Diff -> Diff
align (Diff {doc :: Diff -> Doc Ann
doc = Doc Ann
docOld, Bool
same :: Bool
same :: Diff -> Bool
..}) = Diff {doc :: Doc Ann
doc = forall ann. Doc ann -> Doc ann
Pretty.align Doc Ann
docOld, Bool
same :: Bool
same :: Bool
.. }

hardline :: Diff
hardline :: Diff
hardline = Doc Ann -> Diff
token forall ann. Doc ann
Pretty.hardline

minus :: Diff -> Diff
minus :: Diff -> Diff
minus Diff
l = (Diff
"- " forall a. Semigroup a => a -> a -> a
<> Diff
l) { same :: Bool
same = Bool
False }

plus :: Diff -> Diff
plus :: Diff -> Diff
plus Diff
r = (Diff
"+ " forall a. Semigroup a => a -> a -> a
<> Diff
r) { same :: Bool
same = Bool
False }

difference :: Diff -> Diff -> Diff
difference :: Diff -> Diff -> Diff
difference Diff
l Diff
r = Diff -> Diff
align (Diff -> Diff
minus Diff
l forall a. Semigroup a => a -> a -> a
<> Diff
hardline forall a. Semigroup a => a -> a -> a
<> Diff -> Diff
plus Diff
r)

token :: Doc Ann -> Diff
token :: Doc Ann -> Diff
token Doc Ann
doc = Diff {Bool
Doc Ann
same :: Bool
doc :: Doc Ann
doc :: Doc Ann
same :: Bool
..}
  where
    same :: Bool
same = Bool
True

format :: Diff -> Diff -> Diff
format :: Diff -> Diff -> Diff
format Diff
suffix Diff
doc = Diff
doc forall a. Semigroup a => a -> a -> a
<> (if Diff -> Bool
same Diff
doc then Diff
suffix else Diff
hardline)

builtin :: Doc Ann -> Diff
builtin :: Doc Ann -> Diff
builtin Doc Ann
doc = Doc Ann -> Diff
token (Doc Ann -> Doc Ann
Internal.builtin Doc Ann
doc)

keyword :: Doc Ann -> Diff
keyword :: Doc Ann -> Diff
keyword Doc Ann
doc = Doc Ann -> Diff
token (Doc Ann -> Doc Ann
Internal.keyword Doc Ann
doc)

operator :: Doc Ann -> Diff
operator :: Doc Ann -> Diff
operator Doc Ann
doc = Doc Ann -> Diff
token (Doc Ann -> Doc Ann
Internal.operator Doc Ann
doc)

colon :: Diff
colon :: Diff
colon = Doc Ann -> Diff
token Doc Ann
Internal.colon

comma :: Diff
comma :: Diff
comma = Doc Ann -> Diff
token Doc Ann
Internal.comma

dot :: Diff
dot :: Diff
dot = Doc Ann -> Diff
token Doc Ann
Internal.dot

equals :: Diff
equals :: Diff
equals = Doc Ann -> Diff
token Doc Ann
Internal.equals

forall_ :: Diff
forall_ :: Diff
forall_ = Doc Ann -> Diff
token (CharacterSet -> Doc Ann
Internal.forall_ CharacterSet
Internal.Unicode)

lambda :: Diff
lambda :: Diff
lambda = Doc Ann -> Diff
token (CharacterSet -> Doc Ann
Internal.lambda CharacterSet
Internal.Unicode)

langle :: Diff
langle :: Diff
langle = Doc Ann -> Diff
token Doc Ann
Internal.langle

lbrace :: Diff
lbrace :: Diff
lbrace = Doc Ann -> Diff
token Doc Ann
Internal.lbrace

lbracket :: Diff
lbracket :: Diff
lbracket = Doc Ann -> Diff
token Doc Ann
Internal.lbracket

lparen :: Diff
lparen :: Diff
lparen = Doc Ann -> Diff
token Doc Ann
Internal.lparen

pipe :: Diff
pipe :: Diff
pipe = Doc Ann -> Diff
token Doc Ann
Internal.pipe

rangle :: Diff
rangle :: Diff
rangle = Doc Ann -> Diff
token Doc Ann
Internal.rangle

rarrow :: Diff
rarrow :: Diff
rarrow = Doc Ann -> Diff
token (CharacterSet -> Doc Ann
Internal.rarrow CharacterSet
Internal.Unicode)

rbrace :: Diff
rbrace :: Diff
rbrace = Doc Ann -> Diff
token Doc Ann
Internal.rbrace

rbracket :: Diff
rbracket :: Diff
rbracket = Doc Ann -> Diff
token Doc Ann
Internal.rbracket

rparen :: Diff
rparen :: Diff
rparen = Doc Ann -> Diff
token Doc Ann
Internal.rparen

-- | Render the difference between the normal form of two expressions
diffNormalized :: (Eq a, Pretty a) => Expr s a -> Expr s a -> Diff
diffNormalized :: forall a s. (Eq a, Pretty a) => Expr s a -> Expr s a -> Diff
diffNormalized Expr s a
l0 Expr s a
r0 = forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
Dhall.Diff.diff forall {s}. Expr s a
l1 forall {s}. Expr s a
r1
  where
    l1 :: Expr s a
l1 = forall s a. Expr s a -> Expr s a
Normalize.alphaNormalize (forall a s t. Eq a => Expr s a -> Expr t a
Normalize.normalize Expr s a
l0)
    r1 :: Expr s a
r1 = forall s a. Expr s a -> Expr s a
Normalize.alphaNormalize (forall a s t. Eq a => Expr s a -> Expr t a
Normalize.normalize Expr s a
r0)

diffPrimitive :: Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive :: forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive a -> Diff
f a
l a
r
    | a
l forall a. Eq a => a -> a -> Bool
== a
r    = Diff
ignore
    | Bool
otherwise = Diff -> Diff -> Diff
difference (a -> Diff
f a
l) (a -> Diff
f a
r)

diffLabel :: Text -> Text -> Diff
diffLabel :: Text -> Text -> Diff
diffLabel = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Doc Ann
Internal.prettyLabel)

diffLabels :: [Text] -> [Text] -> Diff
diffLabels :: [Text] -> [Text] -> Diff
diffLabels [Text]
ksL [Text]
ksR =
    [Diff] -> Diff
braced ([Diff]
diffFieldNames forall a. Semigroup a => a -> a -> a
<> (if Bool
anyEqual then [ Diff
ignore ] else []))
  where
    setL :: Set Text
setL = forall a. Ord a => [a] -> Set a
Data.Set.fromList [Text]
ksL
    setR :: Set Text
setR = forall a. Ord a => [a] -> Set a
Data.Set.fromList [Text]
ksR

    extraL :: Set Text
extraL = forall a. Ord a => Set a -> Set a -> Set a
Data.Set.difference Set Text
setL Set Text
setR
    extraR :: Set Text
extraR = forall a. Ord a => Set a -> Set a -> Set a
Data.Set.difference Set Text
setR Set Text
setL

    diffFieldNames :: [Diff]
diffFieldNames = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall {a}. (Diff -> a) -> Text -> [a]
adapt Diff -> Diff
minus) Set Text
extraL forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall {a}. (Diff -> a) -> Text -> [a]
adapt Diff -> Diff
plus) Set Text
extraR
      where
        adapt :: (Diff -> a) -> Text -> [a]
adapt Diff -> a
sign Text
key = [ Diff -> a
sign (Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
key)) ]

    anyEqual :: Bool
anyEqual = Bool -> Bool
not (forall a. Set a -> Bool
Data.Set.null (forall a. Ord a => Set a -> Set a -> Set a
Data.Set.intersection Set Text
setL Set Text
setR))

diffNatural :: Natural -> Natural -> Diff
diffNatural :: Natural -> Natural -> Diff
diffNatural = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Doc Ann
Internal.prettyNatural)

diffDouble :: DhallDouble -> DhallDouble -> Diff
diffDouble :: DhallDouble -> DhallDouble -> Diff
diffDouble = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Doc Ann
Internal.prettyDouble forall b c a. (b -> c) -> (a -> b) -> a -> c
. DhallDouble -> Double
getDhallDouble)

diffDateLiteral :: Time.Day -> Time.Day -> Diff
diffDateLiteral :: Day -> Day -> Diff
diffDateLiteral =
    forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr @(Expr Void Void) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. Day -> Expr s a
DateLiteral)

diffTimeLiteral :: Time.TimeOfDay -> Word -> Time.TimeOfDay -> Word -> Diff
diffTimeLiteral :: TimeOfDay -> Word -> TimeOfDay -> Word -> Diff
diffTimeLiteral TimeOfDay
tL Word
pL TimeOfDay
tR Word
pR =
    forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive
        (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr @(Expr Void Void) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall s a. TimeOfDay -> Word -> Expr s a
TimeLiteral)
        (TimeOfDay
tL, Word
pL)
        (TimeOfDay
tR, Word
pR)

diffTimeZoneLiteral :: Time.TimeZone -> Time.TimeZone -> Diff
diffTimeZoneLiteral :: TimeZone -> TimeZone -> Diff
diffTimeZoneLiteral =
    forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive
        (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr @(Expr Void Void) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. TimeZone -> Expr s a
TimeZoneLiteral)

diffConst :: Const -> Const -> Diff
diffConst :: Const -> Const -> Diff
diffConst = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. Const -> Doc Ann
Internal.prettyConst)

diffBool :: Bool -> Bool -> Diff
diffBool :: Bool -> Bool -> Diff
diffBool = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive Bool -> Diff
bool
  where
    bool :: Bool -> Diff
bool Bool
True  = Doc Ann -> Diff
builtin Doc Ann
"True"
    bool Bool
False = Doc Ann -> Diff
builtin Doc Ann
"False"

diffInteger :: Integer -> Integer -> Diff
diffInteger :: Integer -> Integer -> Diff
diffInteger = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Doc Ann
Internal.prettyNumber)

diffInt :: Int -> Int -> Diff
diffInt :: Int -> Int -> Diff
diffInt = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Doc Ann
Internal.prettyInt)

diffVar :: Var -> Var -> Diff
diffVar :: Var -> Var -> Diff
diffVar (V Text
xL Int
nL) (V Text
xR Int
nR) =
    Diff -> Diff -> Diff
format forall a. Monoid a => a
mempty Diff
label forall a. Semigroup a => a -> a -> a
<> if Diff -> Bool
same Diff
natural then forall a. Monoid a => a
mempty else Diff
"@" forall a. Semigroup a => a -> a -> a
<> Diff
natural
  where
    label :: Diff
label = Text -> Text -> Diff
diffLabel Text
xL Text
xR

    natural :: Diff
natural = Int -> Int -> Diff
diffInt Int
nL Int
nR

diffPretty :: (Eq a, Pretty a) => a -> a -> Diff
diffPretty :: forall a. (Eq a, Pretty a) => a -> a -> Diff
diffPretty = forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. Pretty a => a -> Doc ann
Pretty.pretty)

diffMaybe :: Diff -> (a -> a -> Diff) -> (Maybe a -> Maybe a -> Diff)
diffMaybe :: forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe Diff
_ a -> a -> Diff
_ Maybe a
Nothing Maybe a
Nothing =
    forall a. Monoid a => a
mempty
diffMaybe Diff
prefix a -> a -> Diff
_ Maybe a
Nothing (Just a
_) =
    Diff -> Diff -> Diff
difference forall a. Monoid a => a
mempty (Diff
prefix forall a. Semigroup a => a -> a -> a
<> Diff
ignore)
diffMaybe Diff
prefix a -> a -> Diff
_ (Just a
_) Maybe a
Nothing =
    Diff -> Diff -> Diff
difference (Diff
prefix forall a. Semigroup a => a -> a -> a
<> Diff
ignore) forall a. Monoid a => a
mempty
diffMaybe Diff
prefix a -> a -> Diff
f (Just a
l) (Just a
r) =
    Diff
prefix forall a. Semigroup a => a -> a -> a
<> a -> a -> Diff
f a
l a
r

enclosed
    :: Diff
    -> Diff
    -> Diff
    -> [Diff]
    -> Diff
enclosed :: Diff -> Diff -> Diff -> [Diff] -> Diff
enclosed Diff
l Diff
_ Diff
r []   = Diff
l forall a. Semigroup a => a -> a -> a
<> Diff
r
enclosed Diff
l Diff
m Diff
r [Diff]
docs = Diff -> Diff
align (forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Semigroup a => a -> a -> a
(<>) [Diff]
prefixes [Diff]
docs) forall a. Semigroup a => a -> a -> a
<> Diff
suffix)
  where
    prefixes :: [Diff]
prefixes = Diff
l forall a. a -> [a] -> [a]
: forall a. a -> [a]
repeat (Diff
hardline forall a. Semigroup a => a -> a -> a
<> Diff
m)

    suffix :: Diff
suffix = Diff
hardline forall a. Semigroup a => a -> a -> a
<> Diff
r

enclosed'
    :: Diff
    -> Diff
    -> NonEmpty (Diff)
    -> Diff
enclosed' :: Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
l Diff
m NonEmpty Diff
docs =
    Diff -> Diff
align (forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold (forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
Data.List.NonEmpty.zipWith forall a. Semigroup a => a -> a -> a
(<>) NonEmpty Diff
prefixes NonEmpty Diff
docs))
  where
    prefixes :: NonEmpty Diff
prefixes = Diff
l forall a. a -> [a] -> NonEmpty a
:| forall a. a -> [a]
repeat (Diff
hardline forall a. Semigroup a => a -> a -> a
<> Diff
m)

diffKeyVals
    :: (Eq a, Pretty a)
    => Diff
    -> Map Text (RecordField Void a)
    -> Map Text (RecordField Void a)
    -> [Diff]
diffKeyVals :: forall a.
(Eq a, Pretty a) =>
Diff
-> Map Text (RecordField Void a)
-> Map Text (RecordField Void a)
-> [Diff]
diffKeyVals Diff
assign Map Text (RecordField Void a)
kvsL Map Text (RecordField Void a)
kvsR = forall a.
Diff -> (a -> a -> Diff) -> Map Text a -> Map Text a -> [Diff]
diffKeysWith Diff
assign forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff
    (forall s a. RecordField s a -> Expr s a
recordFieldValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Text (RecordField Void a)
kvsL)
    (forall s a. RecordField s a -> Expr s a
recordFieldValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Text (RecordField Void a)
kvsR)

diffKeysWith
    :: Diff
    -> (a -> a -> Diff)
    -> Map Text a
    -> Map Text a
    -> [Diff]
diffKeysWith :: forall a.
Diff -> (a -> a -> Diff) -> Map Text a -> Map Text a -> [Diff]
diffKeysWith Diff
assign a -> a -> Diff
diffVals Map Text a
kvsL Map Text a
kvsR =
    [Diff]
diffFieldNames forall a. Semigroup a => a -> a -> a
<> [Diff]
diffFieldValues forall a. Semigroup a => a -> a -> a
<> (if Bool
anyEqual then [ Diff
ignore ] else [])
  where
    ksL :: Set Text
ksL = forall k v. Map k v -> Set k
Dhall.Map.keysSet Map Text a
kvsL
    ksR :: Set Text
ksR = forall k v. Map k v -> Set k
Dhall.Map.keysSet Map Text a
kvsR

    extraL :: Set Text
extraL = forall a. Ord a => Set a -> Set a -> Set a
Data.Set.difference Set Text
ksL Set Text
ksR
    extraR :: Set Text
extraR = forall a. Ord a => Set a -> Set a -> Set a
Data.Set.difference Set Text
ksR Set Text
ksL

    diffFieldNames :: [Diff]
diffFieldNames = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Diff -> Diff) -> Text -> [Diff]
adapt Diff -> Diff
minus) Set Text
extraL forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Diff -> Diff) -> Text -> [Diff]
adapt Diff -> Diff
plus) Set Text
extraR
      where
        adapt :: (Diff -> Diff) -> Text -> [Diff]
adapt Diff -> Diff
sign Text
key =
            [   Diff -> Diff
sign (Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
key))
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff
assign
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
            ]

    shared :: Map Text Diff
shared = forall k a b c.
Ord k =>
(a -> b -> c) -> Map k a -> Map k b -> Map k c
Dhall.Map.intersectionWith a -> a -> Diff
diffVals Map Text a
kvsL Map Text a
kvsR

    diffFieldValues :: [Diff]
diffFieldValues =
        forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Diff -> Bool
same) (forall m k a. (Monoid m, Ord k) => (k -> a -> m) -> Map k a -> m
Dhall.Map.foldMapWithKey Text -> Diff -> [Diff]
adapt Map Text Diff
shared)
      where
        adapt :: Text -> Diff -> [Diff]
adapt Text
key Diff
doc =
            [   (if Set Text
ksL forall a. Eq a => a -> a -> Bool
== Set Text
ksR then forall a. Monoid a => a
mempty else Diff
"  ")
            forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
key)
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff
assign
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff
doc
            ]

    anyEqual :: Bool
anyEqual = Any -> Bool
getAny (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Bool -> Any
Any forall b c a. (b -> c) -> (a -> b) -> a -> c
. Diff -> Bool
same) Map Text Diff
shared)

braced :: [Diff] -> Diff
braced :: [Diff] -> Diff
braced = Diff -> Diff -> Diff -> [Diff] -> Diff
enclosed (Diff
lbrace forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Diff
comma forall a. Semigroup a => a -> a -> a
<> Diff
" ") Diff
rbrace

angled :: [Diff] -> Diff
angled :: [Diff] -> Diff
angled = Diff -> Diff -> Diff -> [Diff] -> Diff
enclosed (Diff
langle forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Diff
pipe forall a. Semigroup a => a -> a -> a
<> Diff
" ") Diff
rangle

bracketed :: [Diff] -> Diff
bracketed :: [Diff] -> Diff
bracketed = Diff -> Diff -> Diff -> [Diff] -> Diff
enclosed (Diff
lbracket forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Diff
comma forall a. Semigroup a => a -> a -> a
<> Diff
" ") Diff
rbracket

diffText :: Text -> Text -> Diff
diffText :: Text -> Text -> Diff
diffText Text
l Text
r = Diff
"\"" forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap PolyDiff String String -> Diff
prettyPart [PolyDiff String String]
parts forall a. Semigroup a => a -> a -> a
<> Diff
"\""
  where
    -- TODO: check for color support from the TTY
    colorDiff :: a -> String -> a
colorDiff a
colorCode String
chars =
            a
"\ESC["
        forall a. Semigroup a => a -> a -> a
<>  a
colorCode
        forall a. Semigroup a => a -> a -> a
<>  a
"m"
        forall a. Semigroup a => a -> a -> a
<>  forall a. IsString a => String -> a
fromString String
chars
        forall a. Semigroup a => a -> a -> a
<>  a
"\ESC[0m"

    prettyPart :: PolyDiff String String -> Diff
prettyPart PolyDiff String String
part =
      case PolyDiff String String
part of
        -- Only present in left
        Algo.Diff.First  String
chars ->
            -- Red background
            (forall {a}. (Semigroup a, IsString a) => a -> String -> a
colorDiff Diff
"41" String
chars) { same :: Bool
same = Bool
False }

        -- Only present in right
        Algo.Diff.Second String
chars ->
            -- Green background
            (forall {a}. (Semigroup a, IsString a) => a -> String -> a
colorDiff Diff
"42" String
chars) { same :: Bool
same = Bool
False }

        -- Present in both
        Algo.Diff.Both String
_ String
chars ->
            -- Dim foreground
            forall {a}. (Semigroup a, IsString a) => a -> String -> a
colorDiff Diff
"2" String
chars

    parts :: [PolyDiff String String]
parts = forall a. Eq a => [a] -> [a] -> [Diff [a]]
Algo.Diff.getGroupedDiff (Text -> String
Data.Text.unpack Text
l) (Text -> String
Data.Text.unpack Text
r)

diffChunks
    :: (Eq a, Pretty a)
    => Chunks Void a -> Chunks Void a -> Diff
diffChunks :: forall a.
(Eq a, Pretty a) =>
Chunks Void a -> Chunks Void a -> Diff
diffChunks Chunks Void a
cL Chunks Void a
cR
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Diff]
chunks             = Diff
"\"\""
  | [Diff
c] <- [Diff]
chunks           = Diff
c
  | Bool
otherwise               = Diff -> Diff
align (Diff -> Diff -> Diff -> [Diff] -> Diff
enclosed Diff
"   " Diff
"++ " Diff
"" [Diff]
chunks)
  where
    toEitherList :: Chunks s a -> [Either Text (Expr s a)]
toEitherList (Chunks [(Text, Expr s a)]
te Text
t) =
        forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Text
a, Expr s a
b) -> [forall a b. a -> Either a b
Left Text
a, forall a b. b -> Either a b
Right Expr s a
b]) [(Text, Expr s a)]
te forall a. [a] -> [a] -> [a]
++ [forall a b. a -> Either a b
Left Text
t]

    diffTextSkeleton :: Diff
diffTextSkeleton = Diff -> Diff -> Diff
difference Diff
textSkeleton Diff
textSkeleton

    chunks :: [Diff]
chunks = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {a}.
(Eq a, Pretty a) =>
Either Text (Expr Void a) -> Either Text (Expr Void a) -> Diff
chunkDiff (forall {s} {a}. Chunks s a -> [Either Text (Expr s a)]
toEitherList Chunks Void a
cL) (forall {s} {a}. Chunks s a -> [Either Text (Expr s a)]
toEitherList Chunks Void a
cR)

    chunkDiff :: Either Text (Expr Void a) -> Either Text (Expr Void a) -> Diff
chunkDiff Either Text (Expr Void a)
a Either Text (Expr Void a)
b =
      case (Either Text (Expr Void a)
a, Either Text (Expr Void a)
b) of
        (Left  Text
x, Left Text
y ) -> Text -> Text -> Diff
diffText Text
x Text
y
        (Right Expr Void a
x, Right Expr Void a
y) -> forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
x Expr Void a
y
        (Either Text (Expr Void a), Either Text (Expr Void a))
_                  -> Diff
diffTextSkeleton

diffBytes :: ByteString -> ByteString -> Diff
diffBytes :: ByteString -> ByteString -> Diff
diffBytes ByteString
l ByteString
r =
    Diff
"0x" forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Diff
diffText (ByteString -> Text
Internal.prettyBase16 ByteString
l) (ByteString -> Text
Internal.prettyBase16 ByteString
r)

diffList
    :: (Eq a, Pretty a)
    => Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList :: forall a.
(Eq a, Pretty a) =>
Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList Seq (Expr Void a)
l Seq (Expr Void a)
r = [Diff] -> Diff
bracketed (forall {a}.
(Eq a, Pretty a) =>
[PolyDiff [Expr Void a] [Expr Void a]] -> [Diff]
loop [PolyDiff [Expr Void a] [Expr Void a]]
parts₀)
  where
    -- Sections of the list that are only in left, only in right, or in both
    parts₀ :: [PolyDiff [Expr Void a] [Expr Void a]]
parts₀ = forall a b. (a -> b -> Bool) -> [a] -> [b] -> [PolyDiff [a] [b]]
Algo.Diff.getGroupedDiffBy forall {a}. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Bool
equal (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Seq (Expr Void a)
l) (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Seq (Expr Void a)
r)

    equal :: Expr Void a -> Expr Void a -> Bool
equal Expr Void a
a Expr Void a
b = Diff -> Bool
same (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
a Expr Void a
b)

    -- Render each element of a list using an extra rendering function f
    prettyElems :: (Diff -> b) -> [Expr s a] -> [b]
prettyElems Diff -> b
f = forall a b. (a -> b) -> [a] -> [b]
map (Diff -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Ann -> Diff
token forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr)

    loop :: [PolyDiff [Expr Void a] [Expr Void a]] -> [Diff]
loop [] =
        forall a. Monoid a => a
mempty
    loop (Algo.Diff.First [Expr Void a]
as : Algo.Diff.Second [Expr Void a]
bs : [PolyDiff [Expr Void a] [Expr Void a]]
parts)
        | forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr Void a]
as forall a. Eq a => a -> a -> Bool
== forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr Void a]
bs = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff [Expr Void a]
as [Expr Void a]
bs forall a. Semigroup a => a -> a -> a
<> [PolyDiff [Expr Void a] [Expr Void a]] -> [Diff]
loop [PolyDiff [Expr Void a] [Expr Void a]]
parts
    loop (PolyDiff [Expr Void a] [Expr Void a]
part : [PolyDiff [Expr Void a] [Expr Void a]]
parts) =
        forall {a} {a} {s} {s}.
(Pretty a, Pretty a) =>
PolyDiff [Expr s a] [Expr s a] -> [Diff]
diffPart PolyDiff [Expr Void a] [Expr Void a]
part forall a. Semigroup a => a -> a -> a
<> [PolyDiff [Expr Void a] [Expr Void a]] -> [Diff]
loop [PolyDiff [Expr Void a] [Expr Void a]]
parts

    diffPart :: PolyDiff [Expr s a] [Expr s a] -> [Diff]
diffPart PolyDiff [Expr s a] [Expr s a]
part =
      case PolyDiff [Expr s a] [Expr s a]
part of
        -- Only present in left
        Algo.Diff.First  [Expr s a]
elements ->
            forall {a} {b} {s}. Pretty a => (Diff -> b) -> [Expr s a] -> [b]
prettyElems Diff -> Diff
minus [Expr s a]
elements

        -- Only present in right
        Algo.Diff.Second [Expr s a]
elements ->
            forall {a} {b} {s}. Pretty a => (Diff -> b) -> [Expr s a] -> [b]
prettyElems Diff -> Diff
plus  [Expr s a]
elements

        -- Present in both
        Algo.Diff.Both [Expr s a]
_ [Expr s a]
_        ->
            forall (f :: * -> *) a. Applicative f => a -> f a
pure Diff
ignore

diffRecord
    :: (Eq a, Pretty a)
    => Map Text (RecordField Void a) -> Map Text (RecordField Void a) -> Diff
diffRecord :: forall a.
(Eq a, Pretty a) =>
Map Text (RecordField Void a)
-> Map Text (RecordField Void a) -> Diff
diffRecord Map Text (RecordField Void a)
kvsL Map Text (RecordField Void a)
kvsR = [Diff] -> Diff
braced (forall a.
(Eq a, Pretty a) =>
Diff
-> Map Text (RecordField Void a)
-> Map Text (RecordField Void a)
-> [Diff]
diffKeyVals Diff
colon Map Text (RecordField Void a)
kvsL Map Text (RecordField Void a)
kvsR)

diffRecordLit
    :: (Eq a, Pretty a)
    => Map Text (RecordField Void a) -> Map Text (RecordField Void a) -> Diff
diffRecordLit :: forall a.
(Eq a, Pretty a) =>
Map Text (RecordField Void a)
-> Map Text (RecordField Void a) -> Diff
diffRecordLit Map Text (RecordField Void a)
kvsL Map Text (RecordField Void a)
kvsR = [Diff] -> Diff
braced (forall a.
(Eq a, Pretty a) =>
Diff
-> Map Text (RecordField Void a)
-> Map Text (RecordField Void a)
-> [Diff]
diffKeyVals Diff
equals Map Text (RecordField Void a)
kvsL Map Text (RecordField Void a)
kvsR)

diffUnion
    :: (Eq a, Pretty a)
    => Map Text (Maybe (Expr Void a)) -> Map Text (Maybe (Expr Void a)) -> Diff
diffUnion :: forall a.
(Eq a, Pretty a) =>
Map Text (Maybe (Expr Void a))
-> Map Text (Maybe (Expr Void a)) -> Diff
diffUnion Map Text (Maybe (Expr Void a))
kvsL Map Text (Maybe (Expr Void a))
kvsR = [Diff] -> Diff
angled (forall a.
Diff -> (a -> a -> Diff) -> Map Text a -> Map Text a -> [Diff]
diffKeysWith Diff
colon Maybe (Expr Void a) -> Maybe (Expr Void a) -> Diff
diffVals Map Text (Maybe (Expr Void a))
kvsL Map Text (Maybe (Expr Void a))
kvsR)
  where
    diffVals :: Maybe (Expr Void a) -> Maybe (Expr Void a) -> Diff
diffVals = forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff

textSkeleton :: Diff
textSkeleton :: Diff
textSkeleton =
        Diff
"\""
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
"\""

skeleton :: Pretty a => Expr s a -> Diff
skeleton :: forall a s. Pretty a => Expr s a -> Diff
skeleton (Lam {}) =
        Diff
lambda
    forall a. Semigroup a => a -> a -> a
<>  Diff
lparen
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
rparen
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
rarrow
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<> Diff
" (a function)"
skeleton (Pi {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
rarrow
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<> Diff
" (a function type)"
skeleton (App Expr s a
Optional Expr s a
_) =
        Diff
"Optional "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App Expr s a
None Expr s a
_) =
        Diff
"None "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Some Expr s a
_) =
        Diff
"Some "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App Expr s a
List Expr s a
_) =
        Diff
"List "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Let {}) =
        Doc Ann -> Diff
keyword Doc Ann
"let"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
equals
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"in"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Annot {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolAnd {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"&&"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolOr {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"||"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolEQ {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"=="
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolNE {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"!="
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolIf {}) =
        Doc Ann -> Diff
keyword Doc Ann
"if"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"then"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"else"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BytesLit {}) =
        Diff
"0x\""
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
"\""
skeleton (NaturalPlus {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"+"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (NaturalTimes {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"*"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (TextLit {}) =
        Diff
textSkeleton
skeleton (TextAppend {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"++"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ListLit Maybe (Expr s a)
_ Seq (Expr s a)
elems)
    | forall (t :: * -> *) a. Foldable t => t a -> Bool
null Seq (Expr s a)
elems =
            Diff
lbracket
        forall a. Semigroup a => a -> a -> a
<>  Diff
rbracket
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff
colon
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    | Bool
otherwise =
            Diff
lbracket
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff
rbracket
skeleton (ListAppend {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"#"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Record {}) =
        Diff
lbrace
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
    forall a. Semigroup a => a -> a -> a
<>  Diff
" (a record type)"
skeleton (RecordLit {}) =
        Diff
lbrace
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
equals
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
    forall a. Semigroup a => a -> a -> a
<> Diff
" (a record)"
skeleton (Union {}) =
        Diff
langle
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
rangle
    forall a. Semigroup a => a -> a -> a
<> Diff
" (a union type)"
skeleton (Combine {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"∧"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (CombineTypes {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"⩓"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Prefer {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"⫽"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (RecordCompletion {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"::"
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Merge {}) =
        Doc Ann -> Diff
keyword Doc Ann
"merge"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ToMap {}) =
        Doc Ann -> Diff
keyword Doc Ann
"toMap"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ShowConstructor {}) =
        Doc Ann -> Diff
keyword Doc Ann
"showConstructor"
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Field {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
dot
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Project {}) =
        Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
dot
    forall a. Semigroup a => a -> a -> a
<>  Diff
lbrace
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
skeleton (With {}) =
         Diff
ignore
    forall a. Semigroup a => a -> a -> a
<>   Diff
" "
    forall a. Semigroup a => a -> a -> a
<>   Doc Ann -> Diff
keyword Doc Ann
"with"
    forall a. Semigroup a => a -> a -> a
<>   Diff
" "
    forall a. Semigroup a => a -> a -> a
<>   Diff
ignore
skeleton Expr s a
x = Doc Ann -> Diff
token (forall a ann. Pretty a => a -> Doc ann
Pretty.pretty Expr s a
x)

mismatch :: Pretty a => Expr s a -> Expr s a -> Diff
mismatch :: forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr s a
l Expr s a
r = Diff -> Diff -> Diff
difference (forall a s. Pretty a => Expr s a -> Diff
skeleton Expr s a
l) (forall a s. Pretty a => Expr s a -> Diff
skeleton Expr s a
r)

-- | Render the difference between two expressions
diff :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff l :: Expr Void a
l@(Lam {}) r :: Expr Void a
r@(Lam {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Diff
rarrow forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs
        (Lam Maybe CharacterSet
_ (FunctionBinding { functionBindingVariable :: forall s a. FunctionBinding s a -> Text
functionBindingVariable = Text
aL, functionBindingAnnotation :: forall s a. FunctionBinding s a -> Expr s a
functionBindingAnnotation = Expr Void a
bL }) Expr Void a
cL)
        (Lam Maybe CharacterSet
_ (FunctionBinding { functionBindingVariable :: forall s a. FunctionBinding s a -> Text
functionBindingVariable = Text
aR, functionBindingAnnotation :: forall s a. FunctionBinding s a -> Expr s a
functionBindingAnnotation = Expr Void a
bR }) Expr Void a
cR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Diff -> Diff
align Diff
doc) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
cL Expr Void a
cR)
      where
        doc :: Diff
doc =   Diff
lambda
            forall a. Semigroup a => a -> a -> a
<>  Diff
lparen
            forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Text -> Text -> Diff
diffLabel Text
aL Text
aR)
            forall a. Semigroup a => a -> a -> a
<>  Diff
colon
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format forall a. Monoid a => a
mempty (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
bL Expr Void a
bR)
            forall a. Semigroup a => a -> a -> a
<>  Diff
rparen

    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR)
diff l :: Expr Void a
l@(Lam {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff Expr Void a
l r :: Expr Void a
r@(Lam {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff l :: Expr Void a
l@(BoolIf {}) r :: Expr Void a
r@(BoolIf {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"      " (Doc Ann -> Diff
keyword Doc Ann
"else" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (BoolIf Expr Void a
aL Expr Void a
bL Expr Void a
cL) (BoolIf Expr Void a
aR Expr Void a
bR Expr Void a
cR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Diff -> Diff
align Diff
doc) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
cL Expr Void a
cR)
      where
        doc :: Diff
doc =   Doc Ann -> Diff
keyword Doc Ann
"if"
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR)
            forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"then"
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
bL Expr Void a
bR
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR)
diff l :: Expr Void a
l@(BoolIf {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff Expr Void a
l r :: Expr Void a
r@(BoolIf {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff l :: Expr Void a
l@(Let {}) r :: Expr Void a
r@(Let {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"    " (Doc Ann -> Diff
keyword Doc Ann
"in" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Let (Binding Maybe Void
_ Text
aL Maybe Void
_ Maybe (Maybe Void, Expr Void a)
bL Maybe Void
_ Expr Void a
cL) Expr Void a
dL) (Let (Binding Maybe Void
_ Text
aR Maybe Void
_ Maybe (Maybe Void, Expr Void a)
bR Maybe Void
_ Expr Void a
cR) Expr Void a
dR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Diff -> Diff
align Diff
doc) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
dL Expr Void a
dR)
      where
        bL' :: Maybe (Expr Void a)
bL' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd Maybe (Maybe Void, Expr Void a)
bL
        bR' :: Maybe (Expr Void a)
bR' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd Maybe (Maybe Void, Expr Void a)
bR

        doc :: Diff
doc =   Doc Ann -> Diff
keyword Doc Ann
"let"
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Text -> Text -> Diff
diffLabel Text
aL Text
aR)
            forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Maybe (Expr Void a)
bL' Maybe (Expr Void a)
bR')
            forall a. Semigroup a => a -> a -> a
<>  Diff
equals
            forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            forall a. Semigroup a => a -> a -> a
<>  forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
cL Expr Void a
cR
    docs Expr Void a
aL Expr Void a
aR = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR)
diff l :: Expr Void a
l@(Let {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff Expr Void a
l r :: Expr Void a
r@(Let {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff l :: Expr Void a
l@(Pi {}) r :: Expr Void a
r@(Pi {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Diff
rarrow forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Pi Maybe CharacterSet
_ Text
aL Expr Void a
bL Expr Void a
cL) (Pi Maybe CharacterSet
_ Text
aR Expr Void a
bR Expr Void a
cR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Diff -> Diff
align Diff
doc) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
cL Expr Void a
cR)
      where
        doc :: Diff
doc | Diff -> Bool
same Diff
docA Bool -> Bool -> Bool
&& Diff -> Bool
same Diff
docB = Diff
ignore
            | Diff -> Bool
same Diff
docA =
                Diff -> Diff -> Diff
format forall a. Monoid a => a
mempty Diff
docB
            | Bool
otherwise =
                    Diff
forall_
                forall a. Semigroup a => a -> a -> a
<>  Diff
lparen
                forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " Diff
docA
                forall a. Semigroup a => a -> a -> a
<>  Diff
colon
                forall a. Semigroup a => a -> a -> a
<>  Diff
" "
                forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format forall a. Monoid a => a
mempty Diff
docB
                forall a. Semigroup a => a -> a -> a
<>  Diff
rparen
          where
            docA :: Diff
docA = Text -> Text -> Diff
diffLabel Text
aL Text
aR

            docB :: Diff
docB = forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
bL Expr Void a
bR

    docs Expr Void a
aL Expr Void a
aR = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR)
diff l :: Expr Void a
l@(Pi {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff Expr Void a
l r :: Expr Void a
r@(Pi {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff (Assert Expr Void a
aL) (Assert Expr Void a
aR) =
    Diff -> Diff
align
        (  Diff
"  " forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
keyword Doc Ann
"assert"
        forall a. Semigroup a => a -> a -> a
<> Diff
hardline forall a. Semigroup a => a -> a -> a
<> Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" " forall a. Semigroup a => a -> a -> a
<> forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR
        )
diff l :: Expr Void a
l@(Assert {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff Expr Void a
l r :: Expr Void a
r@(Assert {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diff Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAnnotatedExpression Expr Void a
l Expr Void a
r

diffAnnotatedExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAnnotatedExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAnnotatedExpression (Merge Expr Void a
aL Expr Void a
bL Maybe (Expr Void a)
cL) (Merge Expr Void a
aR Expr Void a
bR Maybe (Expr Void a)
cR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Doc Ann -> Diff
keyword Doc Ann
"merge"
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR)
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
bL Expr Void a
bR)
        forall a. Semigroup a => a -> a -> a
<>  forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Maybe (Expr Void a)
cL Maybe (Expr Void a)
cR
diffAnnotatedExpression l :: Expr Void a
l@(Merge {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression Expr Void a
l r :: Expr Void a
r@(Merge {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression (ToMap Expr Void a
aL Maybe (Expr Void a)
bL) (ToMap Expr Void a
aR Maybe (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Doc Ann -> Diff
keyword Doc Ann
"toMap"
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR)
        forall a. Semigroup a => a -> a -> a
<>  forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Maybe (Expr Void a)
bL Maybe (Expr Void a)
bR
diffAnnotatedExpression l :: Expr Void a
l@(ToMap {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression Expr Void a
l r :: Expr Void a
r@(ToMap {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression (ShowConstructor Expr Void a
aL) (ShowConstructor Expr Void a
aR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Doc Ann -> Diff
keyword Doc Ann
"showConstructor"
        forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR)
diffAnnotatedExpression l :: Expr Void a
l@(ShowConstructor {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression Expr Void a
l r :: Expr Void a
r@(ShowConstructor {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression (ListLit aL :: Maybe (Expr Void a)
aL@(Just Expr Void a
_) Seq (Expr Void a)
bL) (ListLit Maybe (Expr Void a)
aR Seq (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Diff -> Diff -> Diff
format Diff
" " (forall a.
(Eq a, Pretty a) =>
Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList Seq (Expr Void a)
bL Seq (Expr Void a)
bR)
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Maybe (Expr Void a)
aL Maybe (Expr Void a)
aR)
diffAnnotatedExpression (ListLit Maybe (Expr Void a)
aL Seq (Expr Void a)
bL) (ListLit aR :: Maybe (Expr Void a)
aR@(Just Expr Void a
_) Seq (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Diff -> Diff -> Diff
format Diff
" " (forall a.
(Eq a, Pretty a) =>
Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList Seq (Expr Void a)
bL Seq (Expr Void a)
bR)
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Maybe (Expr Void a)
aL Maybe (Expr Void a)
aR)
diffAnnotatedExpression l :: Expr Void a
l@(Annot {}) r :: Expr Void a
r@(Annot {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Diff
colon forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Annot Expr Void a
aL Expr Void a
bL) (Annot Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Diff -> Diff
align Diff
doc) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
      where
        doc :: Diff
doc = forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOperatorExpression Expr Void a
aL Expr Void a
aR
    docs Expr Void a
aL Expr Void a
aR =
        forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR forall a. a -> [a] -> NonEmpty a
:| []
diffAnnotatedExpression l :: Expr Void a
l@(Annot {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression Expr Void a
l r :: Expr Void a
r@(Annot {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAnnotatedExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOperatorExpression Expr Void a
l Expr Void a
r

{- Whitespace in diffs of operator expressions:

All indentation (whether pretty-printing or diffing) is a multiple of two
spaces, so if the operator is one character long (like ?) then the diff pads
the left margin to two space:

    ␣␣e₀
    ?␣e₁

... but if the operator is two characters long (like ||) then the diff pads
the left margin to four spaces:

     ␣␣␣␣e₀
     ||␣␣e₁
-}
diffOperatorExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOperatorExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOperatorExpression = forall a. (Pretty a, Eq a) => Expr Void a -> Expr Void a -> Diff
diffImportAltExpression

diffImportAltExpression :: (Pretty a, Eq a) => Expr Void a -> Expr Void a -> Diff
diffImportAltExpression :: forall a. (Pretty a, Eq a) => Expr Void a -> Expr Void a -> Diff
diffImportAltExpression l :: Expr Void a
l@(ImportAlt {}) r :: Expr Void a
r@(ImportAlt {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"?" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (ImportAlt Expr Void a
aL Expr Void a
bL) (ImportAlt Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOrExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOrExpression Expr Void a
aL Expr Void a
aR)
diffImportAltExpression l :: Expr Void a
l@(ImportAlt {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffImportAltExpression Expr Void a
l r :: Expr Void a
r@(ImportAlt {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffImportAltExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOrExpression Expr Void a
l Expr Void a
r

diffOrExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOrExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOrExpression l :: Expr Void a
l@(BoolOr {}) r :: Expr Void a
r@(BoolOr {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"    " (Doc Ann -> Diff
operator Doc Ann
"||" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (BoolOr Expr Void a
aL Expr Void a
bL) (BoolOr Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPlusExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPlusExpression Expr Void a
aL Expr Void a
aR)
diffOrExpression l :: Expr Void a
l@(BoolOr {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffOrExpression Expr Void a
l r :: Expr Void a
r@(BoolOr {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffOrExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPlusExpression Expr Void a
l Expr Void a
r

diffPlusExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPlusExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPlusExpression l :: Expr Void a
l@(NaturalPlus {}) r :: Expr Void a
r@(NaturalPlus {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"+" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (NaturalPlus Expr Void a
aL Expr Void a
bL) (NaturalPlus Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTextAppendExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTextAppendExpression Expr Void a
aL Expr Void a
aR)
diffPlusExpression l :: Expr Void a
l@(NaturalPlus {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPlusExpression Expr Void a
l r :: Expr Void a
r@(NaturalPlus {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPlusExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTextAppendExpression Expr Void a
l Expr Void a
r

diffTextAppendExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTextAppendExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTextAppendExpression l :: Expr Void a
l@(TextAppend {}) r :: Expr Void a
r@(TextAppend {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"    " (Doc Ann -> Diff
operator Doc Ann
"++" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (TextAppend Expr Void a
aL Expr Void a
bL) (TextAppend Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffListAppendExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffListAppendExpression Expr Void a
aL Expr Void a
aR)
diffTextAppendExpression l :: Expr Void a
l@(TextAppend {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffTextAppendExpression Expr Void a
l r :: Expr Void a
r@(TextAppend {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffTextAppendExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffListAppendExpression Expr Void a
l Expr Void a
r

diffListAppendExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffListAppendExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffListAppendExpression l :: Expr Void a
l@(ListAppend {}) r :: Expr Void a
r@(ListAppend {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"#" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (ListAppend Expr Void a
aL Expr Void a
bL) (ListAppend Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAndExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAndExpression Expr Void a
aL Expr Void a
aR)
diffListAppendExpression l :: Expr Void a
l@(ListAppend {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffListAppendExpression Expr Void a
l r :: Expr Void a
r@(ListAppend {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffListAppendExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAndExpression Expr Void a
l Expr Void a
r

diffAndExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAndExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffAndExpression l :: Expr Void a
l@(BoolAnd {}) r :: Expr Void a
r@(BoolAnd {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"    " (Doc Ann -> Diff
operator Doc Ann
"&&" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (BoolAnd Expr Void a
aL Expr Void a
bL) (BoolAnd Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineExpression Expr Void a
aL Expr Void a
aR)
diffAndExpression l :: Expr Void a
l@(BoolAnd {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAndExpression Expr Void a
l r :: Expr Void a
r@(BoolAnd {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffAndExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineExpression Expr Void a
l Expr Void a
r

diffCombineExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineExpression l :: Expr Void a
l@(Combine {}) r :: Expr Void a
r@(Combine {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"∧" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Combine Maybe CharacterSet
_ Maybe Text
_ Expr Void a
aL Expr Void a
bL) (Combine Maybe CharacterSet
_ Maybe Text
_ Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPreferExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPreferExpression Expr Void a
aL Expr Void a
aR)
diffCombineExpression l :: Expr Void a
l@(Combine {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffCombineExpression Expr Void a
l r :: Expr Void a
r@(Combine {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffCombineExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPreferExpression Expr Void a
l Expr Void a
r

diffPreferExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPreferExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPreferExpression l :: Expr Void a
l@(Prefer {}) r :: Expr Void a
r@(Prefer {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"⫽" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Prefer Maybe CharacterSet
_ PreferAnnotation
_ Expr Void a
aL Expr Void a
bL) (Prefer Maybe CharacterSet
_ PreferAnnotation
_ Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineTypesExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineTypesExpression Expr Void a
aL Expr Void a
aR)
diffPreferExpression l :: Expr Void a
l@(Prefer {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPreferExpression Expr Void a
l r :: Expr Void a
r@(Prefer {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPreferExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineTypesExpression Expr Void a
l Expr Void a
r

diffCombineTypesExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineTypesExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffCombineTypesExpression l :: Expr Void a
l@(CombineTypes {}) r :: Expr Void a
r@(CombineTypes {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"*" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (CombineTypes Maybe CharacterSet
_ Expr Void a
aL Expr Void a
bL) (CombineTypes Maybe CharacterSet
_ Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTimesExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTimesExpression Expr Void a
aL Expr Void a
aR)
diffCombineTypesExpression l :: Expr Void a
l@(CombineTypes {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffCombineTypesExpression Expr Void a
l r :: Expr Void a
r@(CombineTypes {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffCombineTypesExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTimesExpression Expr Void a
l Expr Void a
r

diffTimesExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTimesExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffTimesExpression l :: Expr Void a
l@(NaturalTimes {}) r :: Expr Void a
r@(NaturalTimes {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"*" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (NaturalTimes Expr Void a
aL Expr Void a
bL) (NaturalTimes Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEqualExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEqualExpression Expr Void a
aL Expr Void a
aR)
diffTimesExpression l :: Expr Void a
l@(NaturalTimes {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffTimesExpression Expr Void a
l r :: Expr Void a
r@(NaturalTimes {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffTimesExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEqualExpression Expr Void a
l Expr Void a
r

diffEqualExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEqualExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEqualExpression l :: Expr Void a
l@(BoolEQ {}) r :: Expr Void a
r@(BoolEQ {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"    " (Doc Ann -> Diff
operator Doc Ann
"==" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (BoolEQ Expr Void a
aL Expr Void a
bL) (BoolEQ Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffNotEqualExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffNotEqualExpression Expr Void a
aL Expr Void a
aR)
diffEqualExpression l :: Expr Void a
l@(BoolEQ {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffEqualExpression Expr Void a
l r :: Expr Void a
r@(BoolEQ {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffEqualExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffNotEqualExpression Expr Void a
l Expr Void a
r

diffNotEqualExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffNotEqualExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffNotEqualExpression l :: Expr Void a
l@(BoolNE {}) r :: Expr Void a
r@(BoolNE {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"    " (Doc Ann -> Diff
operator Doc Ann
"!=" forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (BoolNE Expr Void a
aL Expr Void a
bL) (BoolNE Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEquivalentExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEquivalentExpression Expr Void a
aL Expr Void a
aR)
diffNotEqualExpression l :: Expr Void a
l@(BoolNE {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffNotEqualExpression Expr Void a
l r :: Expr Void a
r@(BoolNE {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffNotEqualExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEquivalentExpression Expr Void a
l Expr Void a
r

diffEquivalentExpression
    :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEquivalentExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffEquivalentExpression l :: Expr Void a
l@(Equivalent {}) r :: Expr Void a
r@(Equivalent {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Doc Ann -> Diff
operator Doc Ann
"≡" forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r)
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Equivalent Maybe CharacterSet
_ Expr Void a
aL Expr Void a
bL) (Equivalent Maybe CharacterSet
_ Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Expr Void a
aL Expr Void a
aR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
bL Expr Void a
bR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Expr Void a
aL Expr Void a
aR)
diffEquivalentExpression l :: Expr Void a
l@(Equivalent {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffEquivalentExpression Expr Void a
l r :: Expr Void a
r@(Equivalent {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffEquivalentExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression Expr Void a
l Expr Void a
r

diffApplicationExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffApplicationExpression l :: Expr Void a
l@(App {}) r :: Expr Void a
r@(App {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty (forall a. NonEmpty a -> NonEmpty a
Data.List.NonEmpty.reverse (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r))
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (App Expr Void a
aL Expr Void a
bL) (App Expr Void a
aR Expr Void a
bR) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
bL Expr Void a
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Some Expr Void a
aL) (Some Expr Void a
aR) =
        forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR forall a. a -> [a] -> NonEmpty a
:| [ Doc Ann -> Diff
builtin Doc Ann
"Some" ]
    docs Expr Void a
aL aR :: Expr Void a
aR@(Some {}) =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
aL Expr Void a
aR)
    docs aL :: Expr Void a
aL@(Some {}) Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
aL Expr Void a
aR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR)
diffApplicationExpression l :: Expr Void a
l@(App {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffApplicationExpression Expr Void a
l r :: Expr Void a
r@(App {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffApplicationExpression (Some Expr Void a
l) (Some Expr Void a
r) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty (Doc Ann -> Diff
builtin Doc Ann
"Some" forall a. a -> [a] -> NonEmpty a
:| [ forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
l Expr Void a
r ])
diffApplicationExpression l :: Expr Void a
l@(Some {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffApplicationExpression Expr Void a
l r :: Expr Void a
r@(Some {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffApplicationExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
l Expr Void a
r

diffWithExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression (With Expr Void a
eL NonEmpty WithComponent
ksL Expr Void a
vL) (With Expr Void a
eR NonEmpty WithComponent
ksR Expr Void a
vR) =
    Diff -> Diff
align
        (   Diff -> Diff -> Diff
format Diff
" " (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffImportExpression Expr Void a
eL Expr Void a
eR)
        forall a. Semigroup a => a -> a -> a
<>  Diff
"with "
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff
align
            (   Diff -> Diff -> Diff
format Diff
" " (NonEmpty Text -> NonEmpty Text -> Diff
diffPath (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WithComponent -> Text
toText NonEmpty WithComponent
ksL) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WithComponent -> Text
toText NonEmpty WithComponent
ksR))
            forall a. Semigroup a => a -> a -> a
<>  Diff
"= "
            forall a. Semigroup a => a -> a -> a
<>  forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffOperatorExpression Expr Void a
vL Expr Void a
vR
            )
        )
  where
    toText :: WithComponent -> Text
toText  WithComponent
WithQuestion  = Text
"?"
    toText (WithLabel Text
k ) = Text
k

    diffPath :: NonEmpty Text -> NonEmpty Text -> Diff
diffPath (Text
kL :| []) (Text
kR :| []) =
        Text -> Text -> Diff
diffLabel Text
kL Text
kR
    diffPath (Text
kL₀ :| Text
kL₁ : [Text]
ksL') (Text
kR₀ :| Text
kR₁ : [Text]
ksR') =
            Diff -> Diff -> Diff
format Diff
"" (Text -> Text -> Diff
diffLabel Text
kL₀ Text
kR₀)
        forall a. Semigroup a => a -> a -> a
<>  Diff
dot
        forall a. Semigroup a => a -> a -> a
<>  NonEmpty Text -> NonEmpty Text -> Diff
diffPath (Text
kL₁ forall a. a -> [a] -> NonEmpty a
:| [Text]
ksL') (Text
kR₁ forall a. a -> [a] -> NonEmpty a
:| [Text]
ksR')
    diffPath (Text
kL :| []) (Text
kR₀ :| Text
kR₁ : [Text]
ksR') =
            Diff -> Diff -> Diff
format Diff
"" (Text -> Text -> Diff
diffLabel Text
kL Text
kR₀)
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff
plus (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
k -> Diff
dot forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
k)) (Text
kR₁ forall a. a -> [a] -> NonEmpty a
:| [Text]
ksR'))
    diffPath (Text
kL₀ :| Text
kL₁ : [Text]
ksL') (Text
kR :| []) =
            Diff -> Diff -> Diff
format Diff
"" (Text -> Text -> Diff
diffLabel Text
kL₀ Text
kR)
        forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff
minus (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
k -> Diff
dot forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
k)) (Text
kL₁ forall a. a -> [a] -> NonEmpty a
:| [Text]
ksL'))
diffWithExpression Expr Void a
l r :: Expr Void a
r@With{} =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffWithExpression l :: Expr Void a
l@With{} Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffWithExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffImportExpression Expr Void a
l Expr Void a
r

diffImportExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffImportExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffImportExpression (Embed a
l) (Embed a
r) =
    forall a. (Eq a, Pretty a) => a -> a -> Diff
diffPretty a
l a
r
diffImportExpression l :: Expr Void a
l@(Embed {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffImportExpression Expr Void a
l r :: Expr Void a
r@(Embed {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffImportExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffRecordCompletionExpression Expr Void a
l Expr Void a
r

diffRecordCompletionExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffRecordCompletionExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffRecordCompletionExpression (RecordCompletion Expr Void a
aL Expr Void a
bL) (RecordCompletion Expr Void a
aR Expr Void a
bR) =
       forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffSelectorExpression Expr Void a
aL Expr Void a
aR forall a. Semigroup a => a -> a -> a
<> Diff
"::" forall a. Semigroup a => a -> a -> a
<> forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffSelectorExpression Expr Void a
bL Expr Void a
bR
diffRecordCompletionExpression l :: Expr Void a
l@(RecordCompletion {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffRecordCompletionExpression Expr Void a
l r :: Expr Void a
r@(RecordCompletion {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffRecordCompletionExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffSelectorExpression Expr Void a
l Expr Void a
r

diffSelectorExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffSelectorExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffSelectorExpression l :: Expr Void a
l@(Field {}) r :: Expr Void a
r@(Field {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Diff
dot forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall a. NonEmpty a -> NonEmpty a
Data.List.NonEmpty.reverse (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r))
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Field Expr Void a
aL (forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel -> Text
bL)) (Field Expr Void a
aR (forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel -> Text
bR)) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Text -> Text -> Diff
diffLabel Text
bL Text
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Project Expr Void a
aL (Left [Text]
bL)) (Project Expr Void a
aR (Left [Text]
bR)) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons ([Text] -> [Text] -> Diff
diffLabels [Text]
bL [Text]
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Project Expr Void a
aL (Right Expr Void a
bL)) (Project Expr Void a
aR (Right Expr Void a
bR)) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
bL Expr Void a
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPrimitiveExpression Expr Void a
aL Expr Void a
aR)
diffSelectorExpression l :: Expr Void a
l@(Field {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffSelectorExpression Expr Void a
l r :: Expr Void a
r@(Field {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffSelectorExpression l :: Expr Void a
l@(Project {}) r :: Expr Void a
r@(Project {}) =
    Diff -> Diff -> NonEmpty Diff -> Diff
enclosed' Diff
"  " (Diff
dot forall a. Semigroup a => a -> a -> a
<> Diff
" ") (forall a. NonEmpty a -> NonEmpty a
Data.List.NonEmpty.reverse (forall {a}.
(Eq a, Pretty a) =>
Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
l Expr Void a
r))
  where
    docs :: Expr Void a -> Expr Void a -> NonEmpty Diff
docs (Field Expr Void a
aL (forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel -> Text
bL)) (Field Expr Void a
aR (forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel ->Text
bR)) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Text -> Text -> Diff
diffLabel Text
bL Text
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Project Expr Void a
aL (Left [Text]
bL)) (Project Expr Void a
aR (Left [Text]
bR)) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons ([Text] -> [Text] -> Diff
diffLabels [Text]
bL [Text]
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Project Expr Void a
aL (Right Expr Void a
bL)) (Project Expr Void a
aR (Right Expr Void a
bR)) =
        forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
bL Expr Void a
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs Expr Void a
aL Expr Void a
aR =
        forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPrimitiveExpression Expr Void a
aL Expr Void a
aR)
diffSelectorExpression l :: Expr Void a
l@(Project {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffSelectorExpression Expr Void a
l r :: Expr Void a
r@(Project {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffSelectorExpression Expr Void a
l Expr Void a
r =
    forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPrimitiveExpression Expr Void a
l Expr Void a
r

diffPrimitiveExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPrimitiveExpression :: forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffPrimitiveExpression (Var Var
aL) (Var Var
aR) =
    Var -> Var -> Diff
diffVar Var
aL Var
aR
diffPrimitiveExpression l :: Expr Void a
l@(Var {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(Var {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (Const Const
aL) (Const Const
aR) =
    Const -> Const -> Diff
diffConst Const
aL Const
aR
diffPrimitiveExpression l :: Expr Void a
l@(Const {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(Const {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Bool Expr Void a
Bool =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Bool Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Bool =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Bytes Expr Void a
Bytes =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Bytes Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Bytes =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (BytesLit ByteString
l) (BytesLit ByteString
r) =
    ByteString -> ByteString -> Diff
diffBytes ByteString
l ByteString
r
diffPrimitiveExpression l :: Expr Void a
l@(BytesLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(BytesLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Natural Expr Void a
Natural =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Natural Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Natural =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalFold Expr Void a
NaturalFold =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalFold Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalFold =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalBuild Expr Void a
NaturalBuild =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalBuild Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalBuild =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalIsZero Expr Void a
NaturalIsZero =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalIsZero Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalIsZero =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalEven Expr Void a
NaturalEven =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalEven Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalEven =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalOdd Expr Void a
NaturalOdd =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalOdd Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalOdd =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalToInteger Expr Void a
NaturalToInteger =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalToInteger Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalToInteger =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalShow Expr Void a
NaturalShow =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalShow Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
NaturalSubtract Expr Void a
NaturalSubtract =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalSubtract Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
NaturalSubtract =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Integer Expr Void a
Integer =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Integer Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Integer =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
IntegerClamp Expr Void a
IntegerClamp =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerClamp Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
IntegerClamp =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
IntegerNegate Expr Void a
IntegerNegate =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerNegate Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
IntegerNegate =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
IntegerShow Expr Void a
IntegerShow =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerShow Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
IntegerShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
IntegerToDouble Expr Void a
IntegerToDouble =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerToDouble Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
IntegerToDouble =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Double Expr Void a
Double =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Double Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Double =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
DoubleShow Expr Void a
DoubleShow =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
DoubleShow Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
DoubleShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Text Expr Void a
Text =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Text Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Text =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
TextReplace Expr Void a
TextReplace =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
TextReplace Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
TextReplace =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
TextShow Expr Void a
TextShow =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
TextShow Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
TextShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Date Expr Void a
Date =
    Diff
"…"
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Date =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Date Expr Void a
r=
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
DateShow Expr Void a
DateShow =
    Diff
"…"
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
DateShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
DateShow Expr Void a
r=
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Time Expr Void a
Time =
    Diff
"…"
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Time =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Time Expr Void a
r=
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
TimeShow Expr Void a
TimeShow =
    Diff
"…"
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
TimeShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
TimeShow Expr Void a
r=
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
TimeZone Expr Void a
TimeZone =
    Diff
"…"
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
TimeZone =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
TimeZone Expr Void a
r=
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
TimeZoneShow Expr Void a
TimeZoneShow =
    Diff
"…"
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
TimeZoneShow =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
TimeZoneShow Expr Void a
r=
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
List Expr Void a
List =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
List Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
List =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (ListLit Maybe (Expr Void a)
Nothing Seq (Expr Void a)
bL) (ListLit Maybe (Expr Void a)
Nothing Seq (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc = Diff -> Diff -> Diff
format Diff
" " (forall a.
(Eq a, Pretty a) =>
Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList Seq (Expr Void a)
bL Seq (Expr Void a)
bR)
diffPrimitiveExpression Expr Void a
ListBuild Expr Void a
ListBuild =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListBuild Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListBuild =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
ListFold Expr Void a
ListFold =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListFold Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListFold =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
ListLength Expr Void a
ListLength =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListLength Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListLength =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
ListHead Expr Void a
ListHead =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListHead Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListHead =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
ListLast Expr Void a
ListLast =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListLast Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListLast =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
ListIndexed Expr Void a
ListIndexed =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListIndexed Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListIndexed =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
ListReverse Expr Void a
ListReverse =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListReverse Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
ListReverse =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
Optional Expr Void a
Optional =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Optional Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
Optional =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
None Expr Void a
None =
    Diff
"…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
None Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@Expr Void a
None =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (BoolLit Bool
aL) (BoolLit Bool
aR) =
    Bool -> Bool -> Diff
diffBool Bool
aL Bool
aR
diffPrimitiveExpression l :: Expr Void a
l@(BoolLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(BoolLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (IntegerLit Integer
aL) (IntegerLit Integer
aR) =
    Integer -> Integer -> Diff
diffInteger Integer
aL Integer
aR
diffPrimitiveExpression l :: Expr Void a
l@(IntegerLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(IntegerLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (NaturalLit Natural
aL) (NaturalLit Natural
aR) =
    Natural -> Natural -> Diff
diffNatural Natural
aL Natural
aR
diffPrimitiveExpression l :: Expr Void a
l@(NaturalLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(NaturalLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (DoubleLit DhallDouble
aL) (DoubleLit DhallDouble
aR) =
    DhallDouble -> DhallDouble -> Diff
diffDouble DhallDouble
aL DhallDouble
aR
diffPrimitiveExpression l :: Expr Void a
l@(DoubleLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(DoubleLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (TextLit Chunks Void a
l) (TextLit Chunks Void a
r) =
    forall a.
(Eq a, Pretty a) =>
Chunks Void a -> Chunks Void a -> Diff
diffChunks Chunks Void a
l Chunks Void a
r
diffPrimitiveExpression l :: Expr Void a
l@(TextLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(TextLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (DateLiteral Day
l) (DateLiteral Day
r) =
    Day -> Day -> Diff
diffDateLiteral Day
l Day
r
diffPrimitiveExpression l :: Expr Void a
l@(DateLiteral {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(DateLiteral {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (TimeLiteral TimeOfDay
tL Word
pL) (TimeLiteral TimeOfDay
tR Word
pR) =
    TimeOfDay -> Word -> TimeOfDay -> Word -> Diff
diffTimeLiteral TimeOfDay
tL Word
pL TimeOfDay
tR Word
pR
diffPrimitiveExpression l :: Expr Void a
l@(TimeLiteral {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(TimeLiteral {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (TimeZoneLiteral TimeZone
l) (TimeZoneLiteral TimeZone
r) =
    TimeZone -> TimeZone -> Diff
diffTimeZoneLiteral TimeZone
l TimeZone
r
diffPrimitiveExpression l :: Expr Void a
l@(TimeZoneLiteral {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(TimeZoneLiteral {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (Record Map Text (RecordField Void a)
aL) (Record Map Text (RecordField Void a)
aR) =
    forall a.
(Eq a, Pretty a) =>
Map Text (RecordField Void a)
-> Map Text (RecordField Void a) -> Diff
diffRecord Map Text (RecordField Void a)
aL Map Text (RecordField Void a)
aR
diffPrimitiveExpression l :: Expr Void a
l@(Record {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(Record {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (RecordLit Map Text (RecordField Void a)
aL) (RecordLit Map Text (RecordField Void a)
aR) =
    forall a.
(Eq a, Pretty a) =>
Map Text (RecordField Void a)
-> Map Text (RecordField Void a) -> Diff
diffRecordLit Map Text (RecordField Void a)
aL Map Text (RecordField Void a)
aR
diffPrimitiveExpression l :: Expr Void a
l@(RecordLit {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(RecordLit {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression (Union Map Text (Maybe (Expr Void a))
aL) (Union Map Text (Maybe (Expr Void a))
aR) =
    forall a.
(Eq a, Pretty a) =>
Map Text (Maybe (Expr Void a))
-> Map Text (Maybe (Expr Void a)) -> Diff
diffUnion Map Text (Maybe (Expr Void a))
aL Map Text (Maybe (Expr Void a))
aR
diffPrimitiveExpression l :: Expr Void a
l@(Union {}) Expr Void a
r =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
l r :: Expr Void a
r@(Union {}) =
    forall a s. Pretty a => Expr s a -> Expr s a -> Diff
mismatch Expr Void a
l Expr Void a
r
diffPrimitiveExpression Expr Void a
aL Expr Void a
aR =
    if Diff -> Bool
same Diff
doc
    then Diff
ignore
    else Diff -> Diff
align (Diff
"( " forall a. Semigroup a => a -> a -> a
<> Diff
doc forall a. Semigroup a => a -> a -> a
<> Diff
hardline forall a. Semigroup a => a -> a -> a
<> Diff
")")
  where
    doc :: Diff
doc = forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR