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

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

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

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

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

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

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

    instance Semigroup Diff where
        Diff Bool
    sameL Doc Ann
    docL <> :: Diff -> Diff -> Diff
    <> Diff Bool
    sameR Doc Ann
    docR = Bool -> Doc Ann -> Diff
    Diff (Bool
    sameL Bool -> Bool -> Bool
    && Bool
    sameR) (Doc Ann
    docL 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
    same :: Bool
    doc :: Doc Ann
    same :: Bool
    doc :: Doc Ann
    ..}
          where
            same :: Bool
    same = Bool
    True

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    diffPretty :: (Eq a, Pretty a) => a -> a -> Diff
    diffPretty :: forall a. (Eq a, Pretty a) => 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 ann. a -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    Pretty.pretty)

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

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

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

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

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

    diffKeysWith
        :: Diff
        -> (a -> a -> Diff)
        -> Map Text a
        -> Map Text a
        -> [Diff]
    diffKeysWith :: forall a.
    Diff -> (a -> a -> Diff) -> Map Text a -> Map Text a -> [Diff]
    diffKeysWith Diff
    assign a -> a -> Diff
    diffVals Map Text a
    kvsL Map Text a
    kvsR =
        [Diff]
    diffFieldNames [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 m a. Monoid m => (a -> m) -> Set a -> m
    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 m a. Monoid m => (a -> m) -> Set a -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap ((Diff -> Diff) -> Text -> [Diff]
    adapt Diff -> Diff
    plus) Set Text
    extraR
          where
            adapt :: (Diff -> Diff) -> Text -> [Diff]
    adapt Diff -> Diff
    sign Text
    key =
                [   Diff -> Diff
    sign (Doc Ann -> Diff
    token (Text -> Doc Ann
    Internal.prettyLabel Text
    key))
                Diff -> Diff -> Diff
    forall a. Semigroup a => a -> a -> a
    <>  Diff
    " "
                Diff -> Diff -> Diff
    forall a. Semigroup a => a -> a -> a
    <>  Diff
    assign
                Diff -> Diff -> Diff
    forall a. Semigroup a => a -> a -> a
    <>  Diff
    " "
                Diff -> Diff -> Diff
    forall a. Semigroup a => a -> a -> a
    <>  Diff
    ignore
                ]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    diffList
        :: (Eq a, Pretty a)
        => Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
    diffList :: forall a.
    (Eq a, Pretty a) =>
    Seq (Expr Void a) -> Seq (Expr Void a) -> Diff
    diffList Seq (Expr Void a)
    l Seq (Expr Void a)
    r = [Diff] -> Diff
    bracketed ([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 a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList Seq (Expr Void a)
    l) (Seq (Expr Void a) -> [Expr Void a]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList Seq (Expr Void a)
    r)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    {- Whitespace in diffs of operator expressions:

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

        ␣␣e₀
        ?␣e₁

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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