{-# 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.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 Doc Ann -> Doc Ann -> Doc Ann
forall a. Semigroup a => a -> a -> a
<> Doc Ann
docR)

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

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

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

        doc :: Doc Ann
doc = String -> Doc Ann
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 :: Bool -> Doc Ann -> Diff
Diff {doc :: Doc Ann
doc = Doc Ann -> Doc Ann
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 Doc Ann
forall ann. Doc ann
Pretty.hardline

minus :: Diff -> Diff
minus :: Diff -> Diff
minus Diff
l = (Diff
"- " Diff -> Diff -> 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
"+ " Diff -> Diff -> 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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
hardline Diff -> Diff -> Diff
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 -> Diff
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 Diff -> Diff -> Diff
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 :: Expr s a -> Expr s a -> Diff
diffNormalized Expr s a
l0 Expr s a
r0 = Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
Dhall.Diff.diff Expr Void a
forall s. Expr s a
l1 Expr Void a
forall s. Expr s a
r1
  where
    l1 :: Expr s a
l1 = Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Normalize.alphaNormalize (Expr s a -> Expr s a
forall a s t. Eq a => Expr s a -> Expr t a
Normalize.normalize Expr s a
l0)
    r1 :: Expr s a
r1 = Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Normalize.alphaNormalize (Expr s a -> Expr s a
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 :: (a -> Diff) -> a -> a -> Diff
diffPrimitive a -> Diff
f a
l a
r
    | a
l a -> a -> Bool
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 = (Text -> Diff) -> Text -> Text -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (Text -> Doc Ann) -> Text -> Diff
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 [Diff] -> [Diff] -> [Diff]
forall a. Semigroup a => a -> a -> a
<> (if Bool
anyEqual then [ Diff
ignore ] else []))
  where
    setL :: Set Text
setL = [Text] -> Set Text
forall a. Ord a => [a] -> Set a
Data.Set.fromList [Text]
ksL
    setR :: Set Text
setR = [Text] -> Set Text
forall a. Ord a => [a] -> Set a
Data.Set.fromList [Text]
ksR

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

    diffFieldNames :: [Diff]
diffFieldNames = (Text -> [Diff]) -> Set Text -> [Diff]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Diff -> Diff) -> Text -> [Diff]
forall a. (Diff -> a) -> Text -> [a]
adapt Diff -> Diff
minus) Set Text
extraL [Diff] -> [Diff] -> [Diff]
forall a. Semigroup a => a -> a -> a
<> (Text -> [Diff]) -> Set Text -> [Diff]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Diff -> Diff) -> Text -> [Diff]
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 (Set Text -> Bool
forall a. Set a -> Bool
Data.Set.null (Set Text -> Set Text -> Set Text
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 = (Natural -> Diff) -> Natural -> Natural -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (Natural -> Doc Ann) -> Natural -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Doc Ann
Internal.prettyNatural)

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

diffDateLiteral :: Time.Day -> Time.Day -> Diff
diffDateLiteral :: Day -> Day -> Diff
diffDateLiteral =
    (Day -> Diff) -> Day -> Day -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (Day -> Doc Ann) -> Day -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s.
Pretty (Expr Void Void) =>
Expr s (Expr Void Void) -> Doc Ann
forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr @(Expr Void Void) (Expr Any (Expr Void Void) -> Doc Ann)
-> (Day -> Expr Any (Expr Void Void)) -> Day -> Doc Ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Expr Any (Expr Void Void)
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 =
    ((TimeOfDay, Word) -> Diff)
-> (TimeOfDay, Word) -> (TimeOfDay, Word) -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive
        (Doc Ann -> Diff
token (Doc Ann -> Diff)
-> ((TimeOfDay, Word) -> Doc Ann) -> (TimeOfDay, Word) -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s.
Pretty (Expr Void Void) =>
Expr s (Expr Void Void) -> Doc Ann
forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr @(Expr Void Void) (Expr Any (Expr Void Void) -> Doc Ann)
-> ((TimeOfDay, Word) -> Expr Any (Expr Void Void))
-> (TimeOfDay, Word)
-> Doc Ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TimeOfDay -> Word -> Expr Any (Expr Void Void))
-> (TimeOfDay, Word) -> Expr Any (Expr Void Void)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry TimeOfDay -> Word -> Expr Any (Expr Void Void)
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 =
    (TimeZone -> Diff) -> TimeZone -> TimeZone -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive
        (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (TimeZone -> Doc Ann) -> TimeZone -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s.
Pretty (Expr Void Void) =>
Expr s (Expr Void Void) -> Doc Ann
forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr @(Expr Void Void) (Expr Any (Expr Void Void) -> Doc Ann)
-> (TimeZone -> Expr Any (Expr Void Void)) -> TimeZone -> Doc Ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeZone -> Expr Any (Expr Void Void)
forall s a. TimeZone -> Expr s a
TimeZoneLiteral)

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

diffBool :: Bool -> Bool -> Diff
diffBool :: Bool -> Bool -> Diff
diffBool = (Bool -> Diff) -> Bool -> Bool -> Diff
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 = (Integer -> Diff) -> Integer -> Integer -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (Integer -> Doc Ann) -> Integer -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Doc Ann
Internal.prettyNumber)

diffInt :: Int -> Int -> Diff
diffInt :: Int -> Int -> Diff
diffInt = (Int -> Diff) -> Int -> Int -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (Int -> Doc Ann) -> Int -> Diff
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 Diff
forall a. Monoid a => a
mempty Diff
label Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> if Diff -> Bool
same Diff
natural then Diff
forall a. Monoid a => a
mempty else Diff
"@" Diff -> Diff -> 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 :: a -> a -> Diff
diffPretty = (a -> Diff) -> a -> a -> Diff
forall a. Eq a => (a -> Diff) -> a -> a -> Diff
diffPrimitive (Doc Ann -> Diff
token (Doc Ann -> Diff) -> (a -> Doc Ann) -> a -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc Ann
forall a ann. Pretty a => a -> Doc ann
Pretty.pretty)

diffMaybe :: Diff -> (a -> a -> Diff) -> (Maybe a -> Maybe a -> Diff)
diffMaybe :: Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe Diff
_ a -> a -> Diff
_ Maybe a
Nothing Maybe a
Nothing =
    Diff
forall a. Monoid a => a
mempty
diffMaybe Diff
prefix a -> a -> Diff
_ Maybe a
Nothing (Just a
_) =
    Diff -> Diff -> Diff
difference Diff
forall a. Monoid a => a
mempty (Diff
prefix Diff -> Diff -> Diff
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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
ignore) Diff
forall a. Monoid a => a
mempty
diffMaybe Diff
prefix a -> a -> Diff
f (Just a
l) (Just a
r) =
    Diff
prefix Diff -> Diff -> Diff
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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
r
enclosed Diff
l Diff
m Diff
r [Diff]
docs = Diff -> Diff
align ([Diff] -> Diff
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ((Diff -> Diff -> Diff) -> [Diff] -> [Diff] -> [Diff]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
(<>) [Diff]
prefixes [Diff]
docs) Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
suffix)
  where
    prefixes :: [Diff]
prefixes = Diff
l Diff -> [Diff] -> [Diff]
forall a. a -> [a] -> [a]
: Diff -> [Diff]
forall a. a -> [a]
repeat (Diff
hardline Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
m)

    suffix :: Diff
suffix = Diff
hardline Diff -> Diff -> Diff
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 (NonEmpty Diff -> Diff
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ((Diff -> Diff -> Diff)
-> NonEmpty Diff -> NonEmpty Diff -> NonEmpty Diff
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
Data.List.NonEmpty.zipWith Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
(<>) NonEmpty Diff
prefixes NonEmpty Diff
docs))
  where
    prefixes :: NonEmpty Diff
prefixes = Diff
l Diff -> [Diff] -> NonEmpty Diff
forall a. a -> [a] -> NonEmpty a
:| Diff -> [Diff]
forall a. a -> [a]
repeat (Diff
hardline Diff -> Diff -> Diff
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 :: 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 = Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Map Text (Expr Void a)
-> Map Text (Expr Void a)
-> [Diff]
forall a.
Diff -> (a -> a -> Diff) -> Map Text a -> Map Text a -> [Diff]
diffKeysWith Diff
assign Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff
    (RecordField Void a -> Expr Void a
forall s a. RecordField s a -> Expr s a
recordFieldValue (RecordField Void a -> Expr Void a)
-> Map Text (RecordField Void a) -> Map Text (Expr Void a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Text (RecordField Void a)
kvsL)
    (RecordField Void a -> Expr Void a
forall s a. RecordField s a -> Expr s a
recordFieldValue (RecordField Void a -> Expr Void a)
-> Map Text (RecordField Void a) -> Map Text (Expr Void a)
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 :: 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 [Diff] -> [Diff] -> [Diff]
forall a. Semigroup a => a -> a -> a
<> [Diff]
diffFieldValues [Diff] -> [Diff] -> [Diff]
forall a. Semigroup a => a -> a -> a
<> (if Bool
anyEqual then [ Diff
ignore ] else [])
  where
    ksL :: Set Text
ksL = Map Text a -> Set Text
forall k v. Map k v -> Set k
Dhall.Map.keysSet Map Text a
kvsL
    ksR :: Set Text
ksR = Map Text a -> Set Text
forall k v. Map k v -> Set k
Dhall.Map.keysSet Map Text a
kvsR

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

    diffFieldNames :: [Diff]
diffFieldNames = (Text -> [Diff]) -> Set Text -> [Diff]
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 [Diff] -> [Diff] -> [Diff]
forall a. Semigroup a => a -> a -> a
<> (Text -> [Diff]) -> Set Text -> [Diff]
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))
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
assign
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
            ]

    shared :: Map Text Diff
shared = (a -> a -> Diff) -> Map Text a -> Map Text a -> Map Text Diff
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 =
        (Diff -> Bool) -> [Diff] -> [Diff]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Diff -> Bool) -> Diff -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Diff -> Bool
same) ((Text -> Diff -> [Diff]) -> Map Text Diff -> [Diff]
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 Set Text -> Set Text -> Bool
forall a. Eq a => a -> a -> Bool
== Set Text
ksR then Diff
forall a. Monoid a => a
mempty else Diff
"  ")
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
key)
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
assign
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
doc
            ]

    anyEqual :: Bool
anyEqual = Any -> Bool
getAny ((Diff -> Any) -> Map Text Diff -> Any
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Bool -> Any
Any (Bool -> Any) -> (Diff -> Bool) -> Diff -> 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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Diff
comma Diff -> Diff -> Diff
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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Diff
pipe Diff -> Diff -> Diff
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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Diff
comma Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Diff
rbracket

diffText :: Text -> Text -> Diff
diffText :: Text -> Text -> Diff
diffText Text
l Text
r = Diff
"\"" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> (PolyDiff String String -> Diff)
-> [PolyDiff String String] -> Diff
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap PolyDiff String String -> Diff
prettyPart [PolyDiff String String]
parts Diff -> Diff -> Diff
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["
        a -> a -> a
forall a. Semigroup a => a -> a -> a
<>  a
colorCode
        a -> a -> a
forall a. Semigroup a => a -> a -> a
<>  a
"m"
        a -> a -> a
forall a. Semigroup a => a -> a -> a
<>  String -> a
forall a. IsString a => String -> a
fromString String
chars
        a -> a -> a
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
            (Diff -> String -> Diff
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
            (Diff -> String -> Diff
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
            Diff -> String -> Diff
forall a. (Semigroup a, IsString a) => a -> String -> a
colorDiff Diff
"2" String
chars

    parts :: [PolyDiff String String]
parts = String -> String -> [PolyDiff String String]
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 :: Chunks Void a -> Chunks Void a -> Diff
diffChunks Chunks Void a
cL Chunks Void a
cR
  | [Diff] -> Bool
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) =
        ((Text, Expr s a) -> [Either Text (Expr s a)])
-> [(Text, Expr s a)] -> [Either Text (Expr s a)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Text
a, Expr s a
b) -> [Text -> Either Text (Expr s a)
forall a b. a -> Either a b
Left Text
a, Expr s a -> Either Text (Expr s a)
forall a b. b -> Either a b
Right Expr s a
b]) [(Text, Expr s a)]
te [Either Text (Expr s a)]
-> [Either Text (Expr s a)] -> [Either Text (Expr s a)]
forall a. [a] -> [a] -> [a]
++ [Text -> Either Text (Expr s 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 = (Either Text (Expr Void a) -> Either Text (Expr Void a) -> Diff)
-> [Either Text (Expr Void a)]
-> [Either Text (Expr Void a)]
-> [Diff]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Either Text (Expr Void a) -> Either Text (Expr Void a) -> Diff
forall a.
(Eq a, Pretty a) =>
Either Text (Expr Void a) -> Either Text (Expr Void a) -> Diff
chunkDiff (Chunks Void a -> [Either Text (Expr Void a)]
forall s a. Chunks s a -> [Either Text (Expr s a)]
toEitherList Chunks Void a
cL) (Chunks Void a -> [Either Text (Expr Void a)]
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) -> Expr Void a -> Expr Void a -> Diff
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

diffList
    :: (Eq a, Pretty a)
    => Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList :: Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
diffList Seq (Expr Void a)
l Seq (Expr Void a)
r = [Diff] -> Diff
bracketed ([PolyDiff [Expr Void a] [Expr Void a]] -> [Diff]
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₀ = (Expr Void a -> Expr Void a -> Bool)
-> [Expr Void a]
-> [Expr Void a]
-> [PolyDiff [Expr Void a] [Expr Void a]]
forall a b. (a -> b -> Bool) -> [a] -> [b] -> [PolyDiff [a] [b]]
Algo.Diff.getGroupedDiffBy Expr Void a -> Expr Void a -> Bool
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Bool
equal (Seq (Expr Void a) -> [Expr Void a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Seq (Expr Void a)
l) (Seq (Expr Void a) -> [Expr Void a]
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 (Expr Void a -> Expr Void a -> Diff
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 = (Expr s a -> b) -> [Expr s a] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (Diff -> b
f (Diff -> b) -> (Expr s a -> Diff) -> Expr s a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Ann -> Diff
token (Doc Ann -> Diff) -> (Expr s a -> Doc Ann) -> Expr s a -> Diff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr s a -> Doc Ann
forall a s. Pretty a => Expr s a -> Doc Ann
Internal.prettyExpr)

    loop :: [PolyDiff [Expr Void a] [Expr Void a]] -> [Diff]
loop [] =
        [Diff]
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)
        | [Expr Void a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr Void a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Expr Void a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr Void a]
bs = (Expr Void a -> Expr Void a -> Diff)
-> [Expr Void a] -> [Expr Void a] -> [Diff]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff [Expr Void a]
as [Expr Void a]
bs [Diff] -> [Diff] -> [Diff]
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) =
        PolyDiff [Expr Void a] [Expr Void a] -> [Diff]
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 [Diff] -> [Diff] -> [Diff]
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 ->
            (Diff -> Diff) -> [Expr s a] -> [Diff]
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 ->
            (Diff -> Diff) -> [Expr s a] -> [Diff]
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]
_        ->
            Diff -> [Diff]
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 :: 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 (Diff
-> Map Text (RecordField Void a)
-> Map Text (RecordField Void a)
-> [Diff]
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 :: 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 (Diff
-> Map Text (RecordField Void a)
-> Map Text (RecordField Void a)
-> [Diff]
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 :: 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 (Diff
-> (Maybe (Expr Void a) -> Maybe (Expr Void a) -> Diff)
-> Map Text (Maybe (Expr Void a))
-> Map Text (Maybe (Expr Void a))
-> [Diff]
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 = Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Maybe (Expr Void a)
-> Maybe (Expr Void a)
-> Diff
forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff

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

skeleton :: Pretty a => Expr s a -> Diff
skeleton :: Expr s a -> Diff
skeleton (Lam {}) =
        Diff
lambda
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
lparen
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rparen
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rarrow
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" (a function)"
skeleton (Pi {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rarrow
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" (a function type)"
skeleton (App Expr s a
Optional Expr s a
_) =
        Diff
"Optional "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App Expr s a
None Expr s a
_) =
        Diff
"None "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Some Expr s a
_) =
        Diff
"Some "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App Expr s a
List Expr s a
_) =
        Diff
"List "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Let {}) =
        Doc Ann -> Diff
keyword Doc Ann
"let"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
equals
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"in"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Annot {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolAnd {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"&&"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolOr {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"||"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolEQ {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"=="
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolNE {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"!="
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolIf {}) =
        Doc Ann -> Diff
keyword Doc Ann
"if"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"then"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"else"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (NaturalPlus {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"+"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (NaturalTimes {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"*"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (TextLit {}) =
        Diff
textSkeleton
skeleton (TextAppend {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"++"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ListLit Maybe (Expr s a)
_ Seq (Expr s a)
elems)
    | Seq (Expr s a) -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Seq (Expr s a)
elems =
            Diff
lbracket
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rbracket
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    | Bool
otherwise =
            Diff
lbracket
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rbracket
skeleton (ListAppend {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"#"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Record {}) =
        Diff
lbrace
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" (a record type)"
skeleton (RecordLit {}) =
        Diff
lbrace
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
equals
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" (a record)"
skeleton (Union {}) =
        Diff
langle
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rangle
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" (a union type)"
skeleton (Combine {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"∧"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (CombineTypes {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"⩓"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Prefer {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"⫽"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (RecordCompletion {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator Doc Ann
"::"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Merge {}) =
        Doc Ann -> Diff
keyword Doc Ann
"merge"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ToMap {}) =
        Doc Ann -> Diff
keyword Doc Ann
"toMap"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ShowConstructor {}) =
        Doc Ann -> Diff
keyword Doc Ann
"showConstructor"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Field {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
dot
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Project {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
dot
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
lbrace
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
skeleton (With {}) =
         Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>   Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>   Doc Ann -> Diff
keyword Doc Ann
"with"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>   Diff
" "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>   Diff
ignore
skeleton Expr s a
x = Doc Ann -> Diff
token (Expr s a -> Doc Ann
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 :: Expr s a -> Expr s a -> Diff
mismatch Expr s a
l Expr s a
r = Diff -> Diff -> Diff
difference (Expr s a -> Diff
forall a s. Pretty a => Expr s a -> Diff
skeleton Expr s a
l) (Expr s a -> Diff
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 :: 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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
lparen
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Text -> Text -> Diff
diffLabel Text
aL Text
aR)
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
forall a. Monoid a => a
mempty (Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
bL Expr Void a
bR)
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rparen

    docs Expr Void a
aL Expr Void a
aR =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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"
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR)
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword Doc Ann
"then"
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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' = ((Maybe Void, Expr Void a) -> Expr Void a)
-> Maybe (Maybe Void, Expr Void a) -> Maybe (Expr Void a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Void, Expr Void a) -> Expr Void a
forall a b. (a, b) -> b
snd Maybe (Maybe Void, Expr Void a)
bL
        bR' :: Maybe (Expr Void a)
bR' = ((Maybe Void, Expr Void a) -> Expr Void a)
-> Maybe (Maybe Void, Expr Void a) -> Maybe (Expr Void a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Void, Expr Void a) -> Expr Void a
forall a b. (a, b) -> b
snd Maybe (Maybe Void, Expr Void a)
bR

        doc :: Diff
doc =   Doc Ann -> Diff
keyword Doc Ann
"let"
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Text -> Text -> Diff
diffLabel Text
aL Text
aR)
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Maybe (Expr Void a)
-> Maybe (Expr Void a)
-> Diff
forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Expr Void a -> Expr Void 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')
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
equals
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Expr Void a -> Expr Void a -> Diff
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 = Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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 Diff
forall a. Monoid a => a
mempty Diff
docB
            | Bool
otherwise =
                    Diff
forall
                Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
lparen
                Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " Diff
docA
                Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
                Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
                Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
forall a. Monoid a => a
mempty Diff
docB
                Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rparen
          where
            docA :: Diff
docA = Text -> Text -> Diff
diffLabel Text
aL Text
aR

            docB :: Diff
docB = Expr Void a -> Expr Void a -> Diff
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 = Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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
"  " Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
keyword Doc Ann
"assert"
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
hardline Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" " Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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"
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
bL Expr Void a
bR)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Maybe (Expr Void a)
-> Maybe (Expr Void a)
-> Diff
forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Expr Void a -> Expr Void 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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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"
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Maybe (Expr Void a)
-> Maybe (Expr Void a)
-> Diff
forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Expr Void a -> Expr Void 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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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"
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
" "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Expr Void a -> Expr Void a -> 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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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
" " (Seq (Expr Void a) -> Seq (Expr Void a) -> 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)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Maybe (Expr Void a)
-> Maybe (Expr Void a)
-> Diff
forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Expr Void a -> Expr Void 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
" " (Seq (Expr Void a) -> Seq (Expr Void a) -> 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)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format Diff
" " (Diff
-> (Expr Void a -> Expr Void a -> Diff)
-> Maybe (Expr Void a)
-> Maybe (Expr Void a)
-> Diff
forall a. Diff -> (a -> a -> Diff) -> Maybe a -> Maybe a -> Diff
diffMaybe (Diff
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") Expr Void a -> Expr Void 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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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 = Expr Void a -> Expr Void a -> Diff
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 =
        Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR Diff -> [Diff] -> NonEmpty Diff
forall a. a -> [a] -> NonEmpty a
:| []
diffAnnotatedExpression l :: Expr Void a
l@(Annot {}) Expr Void a
r =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: Expr Void a -> Expr Void a -> Diff
diffOperatorExpression = Expr Void a -> Expr Void a -> Diff
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 :: 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
"?" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"||" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"+" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"++" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"#" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"&&" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"∧" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"⫽" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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 Void a
_ Expr Void a
aL Expr Void a
bL) (Prefer Maybe CharacterSet
_ PreferAnnotation Void a
_ Expr Void a
aR Expr Void a
bR) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"*" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"*" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"==" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"!=" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"  ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
"≡" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (Expr Void a -> Expr Void a -> NonEmpty 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) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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' Diff
forall a. Monoid a => a
mempty Diff
forall a. Monoid a => a
mempty (NonEmpty Diff -> NonEmpty Diff
forall a. NonEmpty a -> NonEmpty a
Data.List.NonEmpty.reverse (Expr Void a -> Expr Void a -> NonEmpty 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 (App Expr Void a
aL Expr Void a
bL) (App Expr Void a
aR Expr Void a
bR) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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) =
        Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression Expr Void a
aL Expr Void a
aR Diff -> [Diff] -> NonEmpty Diff
forall a. a -> [a] -> NonEmpty a
:| [ Doc Ann -> Diff
builtin Doc Ann
"Some" ]
    docs Expr Void a
aL aR :: Expr Void a
aR@(Some {}) =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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' Diff
forall a. Monoid a => a
mempty Diff
forall a. Monoid a => a
mempty (Doc Ann -> Diff
builtin Doc Ann
"Some" Diff -> [Diff] -> NonEmpty Diff
forall a. a -> [a] -> NonEmpty a
:| [ Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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
" " (Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffImportExpression Expr Void a
eL Expr Void a
eR)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
"with "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff
align
            (   Diff -> Diff -> Diff
format Diff
" " (NonEmpty Text -> NonEmpty Text -> Diff
diffPath ((WithComponent -> Text) -> NonEmpty WithComponent -> NonEmpty Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WithComponent -> Text
toText NonEmpty WithComponent
ksL) ((WithComponent -> Text) -> NonEmpty WithComponent -> NonEmpty Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WithComponent -> Text
toText NonEmpty WithComponent
ksR))
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
"= "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Expr Void a -> Expr Void a -> Diff
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₀)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
dot
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  NonEmpty Text -> NonEmpty Text -> Diff
diffPath (Text
kL₁ Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text]
ksL') (Text
kR₁ Text -> [Text] -> NonEmpty Text
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₀)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff
plus ((Text -> Diff) -> NonEmpty Text -> Diff
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
k -> Diff
dot Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
k)) (Text
kR₁ Text -> [Text] -> NonEmpty Text
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)
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff
minus ((Text -> Diff) -> NonEmpty Text -> Diff
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
k -> Diff
dot Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
token (Text -> Doc Ann
Internal.prettyLabel Text
k)) (Text
kL₁ Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text]
ksL'))
diffWithExpression Expr Void a
l r :: Expr Void a
r@With{} =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: Expr Void a -> Expr Void a -> Diff
diffImportExpression (Embed a
l) (Embed a
r) =
    a -> a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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) =
       Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffSelectorExpression Expr Void a
aL Expr Void a
aR Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
"::" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (NonEmpty Diff -> NonEmpty Diff
forall a. NonEmpty a -> NonEmpty a
Data.List.NonEmpty.reverse (Expr Void a -> Expr Void a -> NonEmpty 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 (Field Expr Void a
aL (FieldSelection Void -> Text
forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel -> Text
bL)) (Field Expr Void a
aR (FieldSelection Void -> Text
forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel -> Text
bR)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
" ") (NonEmpty Diff -> NonEmpty Diff
forall a. NonEmpty a -> NonEmpty a
Data.List.NonEmpty.reverse (Expr Void a -> Expr Void a -> NonEmpty 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 (Field Expr Void a
aL (FieldSelection Void -> Text
forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel -> Text
bL)) (Field Expr Void a
aR (FieldSelection Void -> Text
forall s. FieldSelection s -> Text
Syntax.fieldSelectionLabel ->Text
bR)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
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)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Expr Void a -> Expr Void a -> Diff
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 =
        Diff -> NonEmpty Diff
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 :: 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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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=
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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=
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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=
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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
" " (Seq (Expr Void a) -> Seq (Expr Void a) -> 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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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) =
    Chunks Void a -> Chunks Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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) =
    Map Text (RecordField Void a)
-> Map Text (RecordField Void a) -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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) =
    Map Text (RecordField Void a)
-> Map Text (RecordField Void a) -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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) =
    Map Text (Maybe (Expr Void a))
-> Map Text (Maybe (Expr Void a)) -> Diff
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 =
    Expr Void a -> Expr Void a -> Diff
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 {}) =
    Expr Void a -> Expr Void a -> Diff
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
"( " Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
doc Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
hardline Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
")")
  where
    doc :: Diff
doc = Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diff Expr Void a
aL Expr Void a
aR