    {-# 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