{-# LANGUAGE CPP               #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

{-| 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.Semigroup hiding (diff)
import Data.Sequence (Seq)
import Data.String (IsString(..))
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Doc, Pretty)
import Data.Void (Void)
import Dhall.Syntax (Binding(..), Chunks (..), Const(..), DhallDouble(..), Expr(..), Var(..))
import Dhall.Map (Map)
import Dhall.Set (Set)
import Dhall.Pretty.Internal (Ann)
import Numeric.Natural (Natural)

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

{-| 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 Data.Semigroup.Semigroup Diff where
    Diff sameL :: Bool
sameL docL :: Doc Ann
docL <> :: Diff -> Diff -> Diff
<> Diff sameR :: Bool
sameR docR :: 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 {..}
      where
        same :: Bool
same = Bool
True

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

#if !(MIN_VERSION_base(4,11,0))
    mappend = (<>)
#endif

instance IsString (Diff) where
    fromString :: String -> Diff
fromString string :: String
string = Diff :: Bool -> Doc Ann -> Diff
Diff {..}
      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 = "…"

align :: Diff -> Diff
align :: Diff -> Diff
align (Diff {doc :: Diff -> Doc Ann
doc = Doc Ann
docOld, ..}) = 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, .. }

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

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

plus :: Diff -> Diff
plus :: Diff -> Diff
plus r :: Diff
r = ("+ " 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 l :: Diff
l r :: 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 :: Doc Ann
doc = Diff :: Bool -> Doc Ann -> Diff
Diff {..}
  where
    same :: Bool
same = Bool
True

format :: Diff -> Diff -> Diff
format :: Diff -> Diff -> Diff
format suffix :: Diff
suffix doc :: 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 :: 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 :: 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 :: 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 l0 :: Expr s a
l0 r0 :: 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 f :: a -> Diff
f l :: a
l r :: 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 :: Set Text -> Set Text -> Diff
diffLabels :: Set Text -> Set Text -> Diff
diffLabels ksL :: Set Text
ksL ksR :: Set 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
    extraL :: [Text]
extraL = Set Text -> Set Text -> [Text]
forall a. Ord a => Set a -> Set a -> [a]
Dhall.Set.difference Set Text
ksL Set Text
ksR
    extraR :: [Text]
extraR = Set Text -> Set Text -> [Text]
forall a. Ord a => Set a -> Set a -> [a]
Dhall.Set.difference Set Text
ksR Set Text
ksL

    diffFieldNames :: [Diff]
diffFieldNames = (Text -> [Diff]) -> [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) [Text]
extraL [Diff] -> [Diff] -> [Diff]
forall a. Semigroup a => a -> a -> a
<> (Text -> [Diff]) -> [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) [Text]
extraR
      where
        adapt :: (Diff -> a) -> Text -> [a]
adapt sign :: Diff -> a
sign key :: 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 -> Set Text
forall a. Set a -> Set a
Dhall.Set.toSet Set Text
ksL)
                                   (Set Text -> Set Text
forall a. Set a -> Set a
Dhall.Set.toSet Set Text
ksR)))

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)

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 True  = Doc Ann -> Diff
builtin "True"
    bool False = Doc Ann -> Diff
builtin "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 xL :: Text
xL nL :: Int
nL) (V xR :: Text
xR nR :: 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
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 _ _ Nothing Nothing =
    Diff
forall a. Monoid a => a
mempty
diffMaybe prefix :: Diff
prefix _ Nothing (Just _) =
    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 prefix :: Diff
prefix _ (Just _) 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 prefix :: Diff
prefix f :: a -> a -> Diff
f (Just l :: a
l) (Just r :: 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 l :: Diff
l _ r :: Diff
r []   = Diff
l Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Diff
r
enclosed l :: Diff
l m :: Diff
m r :: Diff
r docs :: [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' l :: Diff
l m :: Diff
m docs :: 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 (Expr Void a)
    -> Map Text (Expr Void a)
    -> [Diff]
diffKeyVals :: Diff -> Map Text (Expr Void a) -> Map Text (Expr Void a) -> [Diff]
diffKeyVals assign :: Diff
assign = 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

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 assign :: Diff
assign diffVals :: a -> a -> Diff
diffVals kvsL :: Map Text a
kvsL kvsR :: 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 sign :: Diff -> Diff
sign key :: 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
forall a. Semigroup a => a -> a -> a
<>  Diff
assign
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
            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 key :: Text
key doc :: 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
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
forall a. Semigroup a => a -> a -> a
<>  Diff
assign
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
            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
comma Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") 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
pipe Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") 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
comma Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") Diff
rbracket

diffText :: Text -> Text -> Diff
diffText :: Text -> Text -> Diff
diffText l :: Text
l r :: Text
r = "\"" 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
<> "\""
  where
    -- TODO: check for color support from the TTY
    colorDiff :: a -> String -> a
colorDiff colorCode :: a
colorCode chars :: String
chars =
            "\ESC["
        a -> a -> a
forall a. Semigroup a => a -> a -> a
<>  a
colorCode
        a -> a -> a
forall a. Semigroup 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
<>  "\ESC[0m"

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

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

        -- Present in both
        Algo.Diff.Both _ chars :: String
chars ->
            -- Dim foreground
            Diff -> String -> Diff
forall a. (Semigroup a, IsString a) => a -> String -> a
colorDiff "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 cL :: Chunks Void a
cL cR :: Chunks Void a
cR
  | [Diff] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Diff]
chunks             = "\"\""
  | [c :: Diff
c] <- [Diff]
chunks           = Diff
c
  | Bool
otherwise               = Diff -> Diff
align (Diff -> Diff -> Diff -> [Diff] -> Diff
enclosed "   " "++ " "" [Diff]
chunks)
  where
    toEitherList :: Chunks s a -> [Either Text (Expr s a)]
toEitherList (Chunks te :: [(Text, Expr s a)]
te t :: 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 (\(a :: Text
a, b :: 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 a :: Either Text (Expr Void a)
a b :: Either Text (Expr Void a)
b =
      case (Either Text (Expr Void a)
a, Either Text (Expr Void a)
b) of
        (Left  x :: Text
x, Left y :: Text
y ) -> Text -> Text -> Diff
diffText Text
x Text
y
        (Right x :: Expr Void a
x, Right y :: 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
        _                  -> 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 l :: Seq (Expr Void a)
l r :: 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 a :: Expr Void a
a b :: 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 f :: 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 as :: [Expr Void a]
as : Algo.Diff.Second bs :: [Expr Void a]
bs : parts :: [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 (part :: PolyDiff [Expr Void a] [Expr Void a]
part : parts :: [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 part :: 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  elements :: [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 elements :: [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 _ _        ->
            Diff -> [Diff]
forall (f :: * -> *) a. Applicative f => a -> f a
pure Diff
ignore

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

diffRecordLit
    :: (Eq a, Pretty a)
    => Map Text (Expr Void a) -> Map Text (Expr Void a) -> Diff
diffRecordLit :: Map Text (Expr Void a) -> Map Text (Expr Void a) -> Diff
diffRecordLit kvsL :: Map Text (Expr Void a)
kvsL kvsR :: Map Text (Expr Void a)
kvsR = [Diff] -> Diff
braced (Diff -> Map Text (Expr Void a) -> Map Text (Expr Void a) -> [Diff]
forall a.
(Eq a, Pretty a) =>
Diff -> Map Text (Expr Void a) -> Map Text (Expr Void a) -> [Diff]
diffKeyVals Diff
equals Map Text (Expr Void a)
kvsL Map Text (Expr 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 kvsL :: Map Text (Maybe (Expr Void a))
kvsL kvsR :: 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
<> " ") 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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  "\""

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
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
rarrow
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Pi {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App Optional _) =
        "Optional "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App None _) =
        "None "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Some _) =
        "Some "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (App List _) =
        "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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Let {}) =
        Doc Ann -> Diff
keyword "let"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
equals
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword "in"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "&&"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "||"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "=="
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "!="
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (BoolIf {}) =
        Doc Ann -> Diff
keyword "if"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword "then"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
keyword "else"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "+"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "*"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "++"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ListLit _ elems :: 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
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
        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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
        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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "#"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
skeleton (RecordLit {}) =
        Diff
lbrace
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
equals
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
rbrace
skeleton (Union {}) =
        Diff
langle
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
colon
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
rangle
skeleton (Combine {}) =
        Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "∧"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "⩓"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Doc Ann -> Diff
operator "⫽"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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 "::"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (Merge {}) =
        Doc Ann -> Diff
keyword "merge"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
skeleton (ToMap {}) =
        Doc Ann -> Diff
keyword "toMap"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>  Diff
ignore
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
    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
forall a. Semigroup a => a -> a -> a
<>   Doc Ann -> Diff
keyword "with"
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>   " "
    Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>   Diff
ignore
skeleton x :: 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 l :: Expr s a
l r :: 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
rarrow Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Text
aL bL :: Expr Void a
bL cL :: Expr Void a
cL) (Lam aR :: Text
aR bR :: Expr Void a
bR cR :: 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 " " (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
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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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' "      " (Doc Ann -> Diff
keyword "else" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL cL :: Expr Void a
cL) (BoolIf aR :: Expr Void a
aR bR :: Expr Void a
bR cR :: 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 "if"
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format " " (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 "then"
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
            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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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' "    " (Doc Ann -> Diff
keyword "in" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 _ aL :: Text
aL _ bL :: Maybe (Maybe Void, Expr Void a)
bL _ cL :: Expr Void a
cL) dL :: Expr Void a
dL) (Let (Binding _ aR :: Text
aR _ bR :: Maybe (Maybe Void, Expr Void a)
bR _ cR :: Expr Void a
cR) dR :: 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 "let"
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format " " (Text -> Text -> Diff
diffLabel Text
aL Text
aR)
            Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format " " (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
<> " ") 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
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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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
rarrow Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Text
aL bL :: Expr Void a
bL cL :: Expr Void a
cL) (Pi aR :: Text
aR bR :: Expr Void a
bR cR :: 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
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
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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 aL :: Expr Void a
aL) (Assert aR :: Expr Void a
aR) =
    Diff -> Diff
align
        (  "  " Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> Doc Ann -> Diff
keyword "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
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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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 aL :: Expr Void a
aL bL :: Expr Void a
bL cL :: Maybe (Expr Void a)
cL) (Merge aR :: Expr Void a
aR bR :: Expr Void a
bR cR :: Maybe (Expr Void a)
cR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Doc Ann -> Diff
keyword "merge"
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format " " (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 " " (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
<> " ") 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 {}) r :: 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 l :: 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 aL :: Expr Void a
aL bL :: Maybe (Expr Void a)
bL) (ToMap aR :: Expr Void a
aR bR :: Maybe (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Doc Ann -> Diff
keyword "toMap"
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  " "
        Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<>  Diff -> Diff -> Diff
format " " (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
<> " ") 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 {}) r :: 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 l :: 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 (ListLit aL :: Maybe (Expr Void a)
aL@(Just _) bL :: Seq (Expr Void a)
bL) (ListLit aR :: Maybe (Expr Void a)
aR bR :: Seq (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Diff -> Diff -> Diff
format " " (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
-> (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
<> " ") 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 aL :: Maybe (Expr Void a)
aL bL :: Seq (Expr Void a)
bL) (ListLit aR :: Maybe (Expr Void a)
aR@(Just _) bR :: Seq (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc =   Diff -> Diff -> Diff
format " " (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
-> (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
<> " ") 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
colon Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (Annot aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "?" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (ImportAlt aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "    " (Doc Ann -> Diff
operator "||" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (BoolOr aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "+" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (NaturalPlus aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "    " (Doc Ann -> Diff
operator "++" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (TextAppend aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "#" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (ListAppend aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "    " (Doc Ann -> Diff
operator "&&" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (BoolAnd aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "∧" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 _ aL :: Expr Void a
aL bL :: Expr Void a
bL) (Combine _ aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "⫽" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 _ aL :: Expr Void a
aL bL :: Expr Void a
bL) (Prefer _ aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "*" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (CombineTypes aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "*" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (NaturalTimes aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "    " (Doc Ann -> Diff
operator "==" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (BoolEQ aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "    " (Doc Ann -> Diff
operator "!=" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> "  ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (BoolNE aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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' "  " (Doc Ann -> Diff
operator "≡" Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (Equivalent aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (App aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL) (Some aR :: 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 "Some" ]
    docs aL :: 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 {}) aR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l) (Some r :: 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 "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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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 l :: Expr Void a
l@With{} r :: Expr Void a
r@With{} =
    Expr Void a -> Expr Void a -> Diff
forall a. (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
diffWithExpression (Expr Void a -> Expr Void a
forall s a. Expr s a -> Expr s a
Syntax.desugarWith Expr Void a
l) (Expr Void a -> Expr Void a
forall s a. Expr s a -> Expr s a
Syntax.desugarWith Expr Void a
r)
diffWithExpression l :: 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{} r :: 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 l :: Expr Void a
l r :: 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 l :: a
l) (Embed r :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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 aL :: Expr Void a
aL bL :: Expr Void a
bL) (RecordCompletion aR :: Expr Void a
aR bR :: 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
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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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
dot Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Text
bL) (Field aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL (Left bL :: Set Text
bL)) (Project aR :: Expr Void a
aR (Left bR :: Set Text
bR)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Set Text -> Set Text -> Diff
diffLabels Set Text
bL Set Text
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Project aL :: Expr Void a
aL (Right bL :: Expr Void a
bL)) (Project aR :: Expr Void a
aR (Right bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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
dot Diff -> Diff -> Diff
forall a. Semigroup a => a -> a -> a
<> " ") (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 aL :: Expr Void a
aL bL :: Text
bL) (Field aR :: Expr Void a
aR bR :: 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 aL :: Expr Void a
aL (Left bL :: Set Text
bL)) (Project aR :: Expr Void a
aR (Left bR :: Set Text
bR)) =
        Diff -> NonEmpty Diff -> NonEmpty Diff
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons (Set Text -> Set Text -> Diff
diffLabels Set Text
bL Set Text
bR) (Expr Void a -> Expr Void a -> NonEmpty Diff
docs Expr Void a
aL Expr Void a
aR)
    docs (Project aL :: Expr Void a
aL (Right bL :: Expr Void a
bL)) (Project aR :: Expr Void a
aR (Right bR :: 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 aL :: Expr Void a
aL aR :: 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 {}) r :: 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 l :: 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 l :: Expr Void a
l r :: 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 aL :: Var
aL) (Var aR :: Var
aR) =
    Var -> Var -> Diff
diffVar Var
aL Var
aR
diffPrimitiveExpression l :: Expr Void a
l@(Var {}) r :: 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 l :: 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 aL :: Const
aL) (Const aR :: Const
aR) =
    Const -> Const -> Diff
diffConst Const
aL Const
aR
diffPrimitiveExpression l :: Expr Void a
l@(Const {}) r :: 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 l :: 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 Bool Bool =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Bool r :: 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 l :: 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 Natural Natural =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Natural r :: 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 l :: 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 NaturalFold NaturalFold =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalFold r :: 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 l :: 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 NaturalBuild NaturalBuild =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalBuild r :: 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 l :: 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 NaturalIsZero NaturalIsZero =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalIsZero r :: 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 l :: 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 NaturalEven NaturalEven =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalEven r :: 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 l :: 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 NaturalOdd NaturalOdd =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalOdd r :: 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 l :: 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 NaturalToInteger NaturalToInteger =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalToInteger r :: 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 l :: 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 NaturalShow NaturalShow =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalShow r :: 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 l :: 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 NaturalSubtract NaturalSubtract =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
NaturalSubtract r :: 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 l :: 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 Integer Integer =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Integer r :: 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 l :: 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 IntegerClamp IntegerClamp =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerClamp r :: 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 l :: 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 IntegerNegate IntegerNegate =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerNegate r :: 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 l :: 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 IntegerShow IntegerShow =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerShow r :: 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 l :: 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 IntegerToDouble IntegerToDouble =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
IntegerToDouble r :: 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 l :: 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 Double Double =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Double r :: 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 l :: 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 DoubleShow DoubleShow =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
DoubleShow r :: 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 l :: 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 Text Text =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Text r :: 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 l :: 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 TextShow TextShow =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
TextShow r :: 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 l :: 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 List List =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
List r :: 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 l :: 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 Nothing bL :: Seq (Expr Void a)
bL) (ListLit Nothing bR :: Seq (Expr Void a)
bR) = Diff -> Diff
align Diff
doc
  where
    doc :: Diff
doc = Diff -> Diff -> Diff
format " " (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 ListBuild ListBuild =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListBuild r :: 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 l :: 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 ListFold ListFold =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListFold r :: 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 l :: 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 ListLength ListLength =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListLength r :: 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 l :: 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 ListHead ListHead =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListHead r :: 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 l :: 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 ListLast ListLast =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListLast r :: 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 l :: 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 ListIndexed ListIndexed =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListIndexed r :: 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 l :: 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 ListReverse ListReverse =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
ListReverse r :: 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 l :: 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 Optional Optional =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
Optional r :: 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 l :: 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 None None =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
None r :: 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 l :: 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 OptionalFold OptionalFold =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
OptionalFold r :: 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 l :: Expr Void a
l r :: Expr Void a
r@Expr Void a
OptionalFold =
    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 OptionalBuild OptionalBuild =
    "…"
diffPrimitiveExpression l :: Expr Void a
l@Expr Void a
OptionalBuild r :: 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 l :: Expr Void a
l r :: Expr Void a
r@Expr Void a
OptionalBuild =
    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 aL :: Bool
aL) (BoolLit aR :: Bool
aR) =
    Bool -> Bool -> Diff
diffBool Bool
aL Bool
aR
diffPrimitiveExpression l :: Expr Void a
l@(BoolLit {}) r :: 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 l :: 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 aL :: Integer
aL) (IntegerLit aR :: Integer
aR) =
    Integer -> Integer -> Diff
diffInteger Integer
aL Integer
aR
diffPrimitiveExpression l :: Expr Void a
l@(IntegerLit {}) r :: 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 l :: 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 aL :: Natural
aL) (NaturalLit aR :: Natural
aR) =
    Natural -> Natural -> Diff
diffNatural Natural
aL Natural
aR
diffPrimitiveExpression l :: Expr Void a
l@(NaturalLit {}) r :: 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 l :: 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 aL :: DhallDouble
aL) (DoubleLit aR :: DhallDouble
aR) =
    DhallDouble -> DhallDouble -> Diff
diffDouble DhallDouble
aL DhallDouble
aR
diffPrimitiveExpression l :: Expr Void a
l@(DoubleLit {}) r :: 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 l :: 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 l :: Chunks Void a
l) (TextLit r :: 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 {}) r :: 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 l :: 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 (Record aL :: Map Text (Expr Void a)
aL) (Record aR :: Map Text (Expr Void a)
aR) =
    Map Text (Expr Void a) -> Map Text (Expr Void a) -> Diff
forall a.
(Eq a, Pretty a) =>
Map Text (Expr Void a) -> Map Text (Expr Void a) -> Diff
diffRecord Map Text (Expr Void a)
aL Map Text (Expr Void a)
aR
diffPrimitiveExpression l :: Expr Void a
l@(Record {}) r :: 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 l :: 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 aL :: Map Text (Expr Void a)
aL) (RecordLit aR :: Map Text (Expr Void a)
aR) =
    Map Text (Expr Void a) -> Map Text (Expr Void a) -> Diff
forall a.
(Eq a, Pretty a) =>
Map Text (Expr Void a) -> Map Text (Expr Void a) -> Diff
diffRecordLit Map Text (Expr Void a)
aL Map Text (Expr Void a)
aR
diffPrimitiveExpression l :: Expr Void a
l@(RecordLit {}) r :: 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 l :: 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 aL :: Map Text (Maybe (Expr Void a))
aL) (Union aR :: 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 {}) r :: 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 l :: 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 aL :: Expr Void a
aL aR :: Expr Void a
aR =
    if Diff -> Bool
same Diff
doc
    then Diff
ignore
    else Diff -> Diff
align ("( " 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
<> ")")
  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