    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE UndecidableInstances #-}

    {-
    (c) The University of Glasgow 2006
    (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
    -}

    {-# OPTIONS_GHC -Wno-orphans #-}
     -- Eq (DeBruijn CoreExpr) and Eq (DeBruijn CoreAlt)

    module GHC.Core.Map.Expr (
       -- * Maps over Core expressions
       CoreMap, emptyCoreMap, extendCoreMap, lookupCoreMap, foldCoreMap,
       -- * Alpha equality
       eqDeBruijnExpr, eqCoreExpr,
       -- * 'TrieMap' class reexports
       TrieMap(..), insertTM, deleteTM,
       lkDFreeVar, xtDFreeVar,
       lkDNamed, xtDNamed,
       (>.>), (|>), (|>>),
     ) where

    import GHC.Prelude

    import GHC.Data.TrieMap
    import GHC.Core.Map.Type
    import GHC.Core
    import GHC.Core.Type
    import GHC.Types.Tickish
    import GHC.Types.Var

    import GHC.Utils.Misc
    import GHC.Utils.Outputable

    import qualified Data.Map    as Map
    import GHC.Types.Name.Env
    import Control.Monad( (>=>) )
    import GHC.Types.Literal (Literal)

    {-
    This module implements TrieMaps over Core related data structures
    like CoreExpr or Type. It is built on the Tries from the TrieMap
    module.

    The code is very regular and boilerplate-like, but there is
    some neat handling of *binders*.  In effect they are deBruijn
    numbered on the fly.

    -}

    ----------------------
    -- Recall that
    --   Control.Monad.(>=>) :: (a -> Maybe b) -> (b -> Maybe c) -> a -> Maybe c

    -- The CoreMap makes heavy use of GenMap. However the CoreMap Types are not
    -- known when defining GenMap so we can only specialize them here.

    {-# SPECIALIZE lkG :: Key CoreMapX     -> CoreMapG a     -> Maybe a #-}
    {-# SPECIALIZE xtG :: Key CoreMapX     -> XT a -> CoreMapG a -> CoreMapG a #-}
    {-# SPECIALIZE mapG :: (a -> b) -> CoreMapG a     -> CoreMapG b #-}
    {-# SPECIALIZE fdG :: (a -> b -> b) -> CoreMapG a     -> b -> b #-}

    {-
    ************************************************************************
    *                                                                      *
                       CoreMap
    *                                                                      *
    ************************************************************************
    -}

    {-
    Note [Binders]
    ~~~~~~~~~~~~~~
     * In general we check binders as late as possible because types are
       less likely to differ than expression structure.  That's why
          cm_lam :: CoreMapG (TypeMapG a)
       rather than
          cm_lam :: TypeMapG (CoreMapG a)

     * We don't need to look at the type of some binders, notably
         - the case binder in (Case _ b _ _)
         - the binders in an alternative
       because they are totally fixed by the context

    Note [Empty case alternatives]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    * For a key (Case e b ty (alt:alts))  we don't need to look the return type
      'ty', because every alternative has that type.

    * For a key (Case e b ty []) we MUST look at the return type 'ty', because
      otherwise (Case (error () "urk") _ Int  []) would compare equal to
                (Case (error () "urk") _ Bool [])
      which is utterly wrong (#6097)

    We could compare the return type regardless, but the wildly common case
    is that it's unnecessary, so we have two fields (cm_case and cm_ecase)
    for the two possibilities.  Only cm_ecase looks at the type.

    See also Note [Empty case alternatives] in GHC.Core.
    -}

    -- | @CoreMap a@ is a map from 'CoreExpr' to @a@.  If you are a client, this
    -- is the type you want.
    newtype CoreMap a = CoreMap (CoreMapG a)

    -- TODO(22292): derive
    instance Functor CoreMap where
        fmap :: forall a b. (a -> b) -> CoreMap a -> CoreMap b
    fmap a -> b
    f = \ (CoreMap CoreMapG a
    m) -> CoreMapG b -> CoreMap b
    forall a. CoreMapG a -> CoreMap a
    CoreMap ((a -> b) -> CoreMapG a -> CoreMapG b
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f CoreMapG a
    m)
        {-# INLINE fmap #-}

    instance TrieMap CoreMap where
        type Key CoreMap = CoreExpr
        emptyTM :: forall a. CoreMap a
    emptyTM = CoreMapG a -> CoreMap a
    forall a. CoreMapG a -> CoreMap a
    CoreMap CoreMapG a
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
        lookupTM :: forall b. Key CoreMap -> CoreMap b -> Maybe b
    lookupTM Key CoreMap
    k (CoreMap CoreMapG b
    m) = Key (GenMap CoreMapX) -> CoreMapG b -> Maybe b
    forall b. Key (GenMap CoreMapX) -> GenMap CoreMapX b -> Maybe b
    forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
    lookupTM (Expr Id -> DeBruijn (Expr Id)
    forall a. a -> DeBruijn a
    deBruijnize Expr Id
    Key CoreMap
    k) CoreMapG b
    m
        alterTM :: forall b. Key CoreMap -> XT b -> CoreMap b -> CoreMap b
    alterTM Key CoreMap
    k XT b
    f (CoreMap CoreMapG b
    m) = CoreMapG b -> CoreMap b
    forall a. CoreMapG a -> CoreMap a
    CoreMap (Key (GenMap CoreMapX) -> XT b -> CoreMapG b -> CoreMapG b
    forall b.
    Key (GenMap CoreMapX)
    -> XT b -> GenMap CoreMapX b -> GenMap CoreMapX b
    forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
    alterTM (Expr Id -> DeBruijn (Expr Id)
    forall a. a -> DeBruijn a
    deBruijnize Expr Id
    Key CoreMap
    k) XT b
    f CoreMapG b
    m)
        foldTM :: forall a b. (a -> b -> b) -> CoreMap a -> b -> b
    foldTM a -> b -> b
    k (CoreMap CoreMapG a
    m) = (a -> b -> b) -> CoreMapG a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k CoreMapG a
    m
        filterTM :: forall a. (a -> Bool) -> CoreMap a -> CoreMap a
    filterTM a -> Bool
    f (CoreMap CoreMapG a
    m) = CoreMapG a -> CoreMap a
    forall a. CoreMapG a -> CoreMap a
    CoreMap ((a -> Bool) -> CoreMapG a -> CoreMapG a
    forall a. (a -> Bool) -> GenMap CoreMapX a -> GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f CoreMapG a
    m)

    -- | @CoreMapG a@ is a map from @DeBruijn CoreExpr@ to @a@.  The extended
    -- key makes it suitable for recursive traversal, since it can track binders,
    -- but it is strictly internal to this module.  If you are including a 'CoreMap'
    -- inside another 'TrieMap', this is the type you want.
    type CoreMapG = GenMap CoreMapX

    type LiteralMap  a = Map.Map Literal a

    -- | @CoreMapX a@ is the base map from @DeBruijn CoreExpr@ to @a@, but without
    -- the 'GenMap' optimization.
    data CoreMapX a
      = CM { forall a. CoreMapX a -> VarMap a
    cm_var   :: VarMap a
           , forall a. CoreMapX a -> LiteralMap a
    cm_lit   :: LiteralMap a
           , forall a. CoreMapX a -> CoercionMapG a
    cm_co    :: CoercionMapG a
           , forall a. CoreMapX a -> TypeMapG a
    cm_type  :: TypeMapG a
           , forall a. CoreMapX a -> CoreMapG (CoercionMapG a)
    cm_cast  :: CoreMapG (CoercionMapG a)
           , forall a. CoreMapX a -> CoreMapG (TickishMap a)
    cm_tick  :: CoreMapG (TickishMap a)
           , forall a. CoreMapX a -> CoreMapG (CoreMapG a)
    cm_app   :: CoreMapG (CoreMapG a)
           , forall a. CoreMapX a -> CoreMapG (BndrMap a)
    cm_lam   :: CoreMapG (BndrMap a)    -- Note [Binders]
           , forall a. CoreMapX a -> CoreMapG (CoreMapG (BndrMap a))
    cm_letn  :: CoreMapG (CoreMapG (BndrMap a))
           , forall a.
    CoreMapX a
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr  :: ListMap CoreMapG (CoreMapG (ListMap BndrMap a))
           , forall a. CoreMapX a -> CoreMapG (ListMap AltMap a)
    cm_case  :: CoreMapG (ListMap AltMap a)
           , forall a. CoreMapX a -> CoreMapG (TypeMapG a)
    cm_ecase :: CoreMapG (TypeMapG a)    -- Note [Empty case alternatives]
         }

    instance Eq (DeBruijn CoreExpr) where
        == :: DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    (==) = DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    eqDeBruijnExpr

    eqDeBruijnExpr :: DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool
    eqDeBruijnExpr :: DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    eqDeBruijnExpr (D CmEnv
    env1 Expr Id
    e1) (D CmEnv
    env2 Expr Id
    e2) = Expr Id -> Expr Id -> Bool
    go Expr Id
    e1 Expr Id
    e2 where
        go :: Expr Id -> Expr Id -> Bool
    go (Var Id
    v1) (Var Id
    v2)             = DeBruijn Id -> DeBruijn Id -> Bool
    eqDeBruijnVar (CmEnv -> Id -> DeBruijn Id
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 Id
    v1) (CmEnv -> Id -> DeBruijn Id
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 Id
    v2)
        go (Lit Literal
    lit1)    (Lit Literal
    lit2)      = Literal
    lit1 Literal -> Literal -> Bool
    forall a. Eq a => a -> a -> Bool
    == Literal
    lit2
        go (Type Mult
    t1)    (Type Mult
    t2)        = DeBruijn Mult -> DeBruijn Mult -> Bool
    eqDeBruijnType (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 Mult
    t1) (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 Mult
    t2)
        -- See Note [Alpha-equality for Coercion arguments]
        go (Coercion {}) (Coercion {}) = Bool
    True
        go (Cast Expr Id
    e1 CoercionR
    co1) (Cast Expr Id
    e2 CoercionR
    co2) = CmEnv -> CoercionR -> DeBruijn CoercionR
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 CoercionR
    co1 DeBruijn CoercionR -> DeBruijn CoercionR -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> CoercionR -> DeBruijn CoercionR
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 CoercionR
    co2 Bool -> Bool -> Bool
    && Expr Id -> Expr Id -> Bool
    go Expr Id
    e1 Expr Id
    e2
        go (App Expr Id
    f1 Expr Id
    a1)   (App Expr Id
    f2 Expr Id
    a2)   = Expr Id -> Expr Id -> Bool
    go Expr Id
    f1 Expr Id
    f2 Bool -> Bool -> Bool
    && Expr Id -> Expr Id -> Bool
    go Expr Id
    a1 Expr Id
    a2
        go (Tick GenTickish 'TickishPassCore
    n1 Expr Id
    e1) (Tick GenTickish 'TickishPassCore
    n2 Expr Id
    e2)
          =  DeBruijn (GenTickish 'TickishPassCore)
    -> DeBruijn (GenTickish 'TickishPassCore) -> Bool
    eqDeBruijnTickish (CmEnv
    -> GenTickish 'TickishPassCore
    -> DeBruijn (GenTickish 'TickishPassCore)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 GenTickish 'TickishPassCore
    n1) (CmEnv
    -> GenTickish 'TickishPassCore
    -> DeBruijn (GenTickish 'TickishPassCore)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 GenTickish 'TickishPassCore
    n2)
          Bool -> Bool -> Bool
    && Expr Id -> Expr Id -> Bool
    go Expr Id
    e1 Expr Id
    e2

        go (Lam Id
    b1 Expr Id
    e1)  (Lam Id
    b2 Expr Id
    e2)
          =  DeBruijn Mult -> DeBruijn Mult -> Bool
    eqDeBruijnType (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 (Id -> Mult
    varType Id
    b1)) (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 (Id -> Mult
    varType Id
    b2))
          Bool -> Bool -> Bool
    && CmEnv -> Maybe Mult -> DeBruijn (Maybe Mult)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 (Id -> Maybe Mult
    varMultMaybe Id
    b1) DeBruijn (Maybe Mult) -> DeBruijn (Maybe Mult) -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> Maybe Mult -> DeBruijn (Maybe Mult)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 (Id -> Maybe Mult
    varMultMaybe Id
    b2)
          Bool -> Bool -> Bool
    && DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    eqDeBruijnExpr (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env1 Id
    b1) Expr Id
    e1) (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env2 Id
    b2) Expr Id
    e2)

        go (Let (NonRec Id
    v1 Expr Id
    r1) Expr Id
    e1) (Let (NonRec Id
    v2 Expr Id
    r2) Expr Id
    e2)
          =  Expr Id -> Expr Id -> Bool
    go Expr Id
    r1 Expr Id
    r2 -- See Note [Alpha-equality for let-bindings]
          Bool -> Bool -> Bool
    && DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    eqDeBruijnExpr (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env1 Id
    v1) Expr Id
    e1) (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env2 Id
    v2) Expr Id
    e2)

        go (Let (Rec [(Id, Expr Id)]
    ps1) Expr Id
    e1) (Let (Rec [(Id, Expr Id)]
    ps2) Expr Id
    e2)
          = [(Id, Expr Id)] -> [(Id, Expr Id)] -> Bool
    forall a b. [a] -> [b] -> Bool
    equalLength [(Id, Expr Id)]
    ps1 [(Id, Expr Id)]
    ps2
          -- See Note [Alpha-equality for let-bindings]
          Bool -> Bool -> Bool
    && (Id -> Id -> Bool) -> [Id] -> [Id] -> Bool
    forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
    all2 (\Id
    b1 Id
    b2 -> DeBruijn Mult -> DeBruijn Mult -> Bool
    eqDeBruijnType (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 (Id -> Mult
    varType Id
    b1))
                                            (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 (Id -> Mult
    varType Id
    b2)))
                  [Id]
    bs1 [Id]
    bs2
          Bool -> Bool -> Bool
    && CmEnv -> [Expr Id] -> DeBruijn [Expr Id]
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1' [Expr Id]
    rs1 DeBruijn [Expr Id] -> DeBruijn [Expr Id] -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> [Expr Id] -> DeBruijn [Expr Id]
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2' [Expr Id]
    rs2
          Bool -> Bool -> Bool
    && DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    eqDeBruijnExpr (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1' Expr Id
    e1) (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2' Expr Id
    e2)
          where
            ([Id]
    bs1,[Expr Id]
    rs1) = [(Id, Expr Id)] -> ([Id], [Expr Id])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [(Id, Expr Id)]
    ps1
            ([Id]
    bs2,[Expr Id]
    rs2) = [(Id, Expr Id)] -> ([Id], [Expr Id])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [(Id, Expr Id)]
    ps2
            env1' :: CmEnv
    env1' = CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env1 [Id]
    bs1
            env2' :: CmEnv
    env2' = CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env2 [Id]
    bs2

        go (Case Expr Id
    e1 Id
    b1 Mult
    t1 [Alt Id]
    a1) (Case Expr Id
    e2 Id
    b2 Mult
    t2 [Alt Id]
    a2)
          | [Alt Id] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Alt Id]
    a1   -- See Note [Empty case alternatives]
          = [Alt Id] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Alt Id]
    a2 Bool -> Bool -> Bool
    && Expr Id -> Expr Id -> Bool
    go Expr Id
    e1 Expr Id
    e2 Bool -> Bool -> Bool
    && CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 Mult
    t1 DeBruijn Mult -> DeBruijn Mult -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 Mult
    t2
          | Bool
    otherwise
          = Expr Id -> Expr Id -> Bool
    go Expr Id
    e1 Expr Id
    e2 Bool -> Bool -> Bool
    && CmEnv -> [Alt Id] -> DeBruijn [Alt Id]
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env1 Id
    b1) [Alt Id]
    a1 DeBruijn [Alt Id] -> DeBruijn [Alt Id] -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> [Alt Id] -> DeBruijn [Alt Id]
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env2 Id
    b2) [Alt Id]
    a2

        go Expr Id
    _ Expr Id
    _ = Bool
    False

    eqDeBruijnTickish :: DeBruijn CoreTickish -> DeBruijn CoreTickish -> Bool
    eqDeBruijnTickish :: DeBruijn (GenTickish 'TickishPassCore)
    -> DeBruijn (GenTickish 'TickishPassCore) -> Bool
    eqDeBruijnTickish (D CmEnv
    env1 GenTickish 'TickishPassCore
    t1) (D CmEnv
    env2 GenTickish 'TickishPassCore
    t2) = GenTickish 'TickishPassCore -> GenTickish 'TickishPassCore -> Bool
    go GenTickish 'TickishPassCore
    t1 GenTickish 'TickishPassCore
    t2 where
        go :: GenTickish 'TickishPassCore -> GenTickish 'TickishPassCore -> Bool
    go (Breakpoint XBreakpoint 'TickishPassCore
    lext Int
    lid [XTickishId 'TickishPassCore]
    lids Module
    lmod) (Breakpoint XBreakpoint 'TickishPassCore
    rext Int
    rid [XTickishId 'TickishPassCore]
    rids Module
    rmod)
            =  Int
    lid Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    rid
            Bool -> Bool -> Bool
    && CmEnv -> [Id] -> DeBruijn [Id]
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 [Id]
    [XTickishId 'TickishPassCore]
    lids DeBruijn [Id] -> DeBruijn [Id] -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> [Id] -> DeBruijn [Id]
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 [Id]
    [XTickishId 'TickishPassCore]
    rids
            Bool -> Bool -> Bool
    && NoExtField
    XBreakpoint 'TickishPassCore
    lext NoExtField -> NoExtField -> Bool
    forall a. Eq a => a -> a -> Bool
    == NoExtField
    XBreakpoint 'TickishPassCore
    rext
            Bool -> Bool -> Bool
    && Module
    lmod Module -> Module -> Bool
    forall a. Eq a => a -> a -> Bool
    == Module
    rmod
        go GenTickish 'TickishPassCore
    l GenTickish 'TickishPassCore
    r = GenTickish 'TickishPassCore
    l GenTickish 'TickishPassCore -> GenTickish 'TickishPassCore -> Bool
    forall a. Eq a => a -> a -> Bool
    == GenTickish 'TickishPassCore
    r

    -- Compares for equality, modulo alpha
    eqCoreExpr :: CoreExpr -> CoreExpr -> Bool
    eqCoreExpr :: Expr Id -> Expr Id -> Bool
    eqCoreExpr Expr Id
    e1 Expr Id
    e2 = DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    eqDeBruijnExpr (Expr Id -> DeBruijn (Expr Id)
    forall a. a -> DeBruijn a
    deBruijnize Expr Id
    e1) (Expr Id -> DeBruijn (Expr Id)
    forall a. a -> DeBruijn a
    deBruijnize Expr Id
    e2)

    {- Note [Alpha-equality for Coercion arguments]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The 'Coercion' constructor only appears in argument positions, and so, if the
    functions are equal, then the arguments must have equal types. Because the
    comparison for coercions (correctly) checks only their types, checking for
    alpha-equality of the coercions is redundant.
    -}

    {- Note [Alpha-equality for let-bindings]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For /recursive/ let-bindings we need to check that the types of the binders
    are alpha-equivalent. Otherwise

      letrec (x : Bool) = x in x

    and

      letrec (y : Char) = y in y

    would be considered alpha-equivalent, which they are obviously not.

    For /non-recursive/ let-bindings, we do not have to check that the types of
    the binders are alpha-equivalent. When the RHSs (the expressions) of the
    non-recursive let-binders are well-formed and well-typed (which we assume they
    are at this point in the compiler), and the RHSs are alpha-equivalent, then the
    bindings must have the same type.

    In addition, it is also worth pointing out that

      letrec { x = e1; y = e2 } in b

    is NOT considered equal to

      letrec { y = e2; x = e1 } in b
    -}

    emptyE :: CoreMapX a
    emptyE :: forall a. CoreMapX a
    emptyE = CM { cm_var :: VarMap a
    cm_var = VarMap a
    forall a. VarMap a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM, cm_lit :: LiteralMap a
    cm_lit = LiteralMap a
    forall a. Map Literal a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
                , cm_co :: CoercionMapG a
    cm_co = CoercionMapG a
    forall a. GenMap CoercionMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM, cm_type :: TypeMapG a
    cm_type = TypeMapG a
    forall a. GenMap TypeMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
                , cm_cast :: CoreMapG (CoercionMapG a)
    cm_cast = CoreMapG (CoercionMapG a)
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM, cm_app :: CoreMapG (CoreMapG a)
    cm_app = CoreMapG (CoreMapG a)
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
                , cm_lam :: CoreMapG (BndrMap a)
    cm_lam = CoreMapG (BndrMap a)
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM, cm_letn :: CoreMapG (CoreMapG (BndrMap a))
    cm_letn = CoreMapG (CoreMapG (BndrMap a))
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
                , cm_letr :: ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr = ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    forall a. ListMap (GenMap CoreMapX) a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM, cm_case :: CoreMapG (ListMap AltMap a)
    cm_case = CoreMapG (ListMap AltMap a)
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
                , cm_ecase :: CoreMapG (TypeMapG a)
    cm_ecase = CoreMapG (TypeMapG a)
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM, cm_tick :: CoreMapG (TickishMap a)
    cm_tick = CoreMapG (TickishMap a)
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM }

    -- TODO(22292): derive
    instance Functor CoreMapX where
        fmap :: forall a b. (a -> b) -> CoreMapX a -> CoreMapX b
    fmap a -> b
    f CM
          { cm_var :: forall a. CoreMapX a -> VarMap a
    cm_var = VarMap a
    cvar, cm_lit :: forall a. CoreMapX a -> LiteralMap a
    cm_lit = LiteralMap a
    clit, cm_co :: forall a. CoreMapX a -> CoercionMapG a
    cm_co = CoercionMapG a
    cco, cm_type :: forall a. CoreMapX a -> TypeMapG a
    cm_type = TypeMapG a
    ctype, cm_cast :: forall a. CoreMapX a -> CoreMapG (CoercionMapG a)
    cm_cast = CoreMapG (CoercionMapG a)
    ccast
          , cm_app :: forall a. CoreMapX a -> CoreMapG (CoreMapG a)
    cm_app = CoreMapG (CoreMapG a)
    capp, cm_lam :: forall a. CoreMapX a -> CoreMapG (BndrMap a)
    cm_lam = CoreMapG (BndrMap a)
    clam, cm_letn :: forall a. CoreMapX a -> CoreMapG (CoreMapG (BndrMap a))
    cm_letn = CoreMapG (CoreMapG (BndrMap a))
    cletn, cm_letr :: forall a.
    CoreMapX a
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr = ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cletr, cm_case :: forall a. CoreMapX a -> CoreMapG (ListMap AltMap a)
    cm_case = CoreMapG (ListMap AltMap a)
    ccase
          , cm_ecase :: forall a. CoreMapX a -> CoreMapG (TypeMapG a)
    cm_ecase = CoreMapG (TypeMapG a)
    cecase, cm_tick :: forall a. CoreMapX a -> CoreMapG (TickishMap a)
    cm_tick = CoreMapG (TickishMap a)
    ctick } = CM
          { cm_var :: VarMap b
    cm_var = (a -> b) -> VarMap a -> VarMap b
    forall a b. (a -> b) -> VarMap a -> VarMap b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f VarMap a
    cvar, cm_lit :: LiteralMap b
    cm_lit = (a -> b) -> LiteralMap a -> LiteralMap b
    forall a b. (a -> b) -> Map Literal a -> Map Literal b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f LiteralMap a
    clit, cm_co :: CoercionMapG b
    cm_co = (a -> b) -> CoercionMapG a -> CoercionMapG b
    forall a b.
    (a -> b) -> GenMap CoercionMapX a -> GenMap CoercionMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f CoercionMapG a
    cco, cm_type :: TypeMapG b
    cm_type = (a -> b) -> TypeMapG a -> TypeMapG b
    forall a b. (a -> b) -> GenMap TypeMapX a -> GenMap TypeMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f TypeMapG a
    ctype
          , cm_cast :: CoreMapG (CoercionMapG b)
    cm_cast = (CoercionMapG a -> CoercionMapG b)
    -> CoreMapG (CoercionMapG a) -> CoreMapG (CoercionMapG b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> CoercionMapG a -> CoercionMapG b
    forall a b.
    (a -> b) -> GenMap CoercionMapX a -> GenMap CoercionMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) CoreMapG (CoercionMapG a)
    ccast, cm_app :: CoreMapG (CoreMapG b)
    cm_app = (CoreMapG a -> CoreMapG b)
    -> CoreMapG (CoreMapG a) -> CoreMapG (CoreMapG b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> CoreMapG a -> CoreMapG b
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) CoreMapG (CoreMapG a)
    capp, cm_lam :: CoreMapG (BndrMap b)
    cm_lam = (BndrMap a -> BndrMap b)
    -> CoreMapG (BndrMap a) -> CoreMapG (BndrMap b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> BndrMap a -> BndrMap b
    forall a b. (a -> b) -> BndrMap a -> BndrMap b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) CoreMapG (BndrMap a)
    clam
          , cm_letn :: CoreMapG (CoreMapG (BndrMap b))
    cm_letn = (CoreMapG (BndrMap a) -> CoreMapG (BndrMap b))
    -> CoreMapG (CoreMapG (BndrMap a))
    -> CoreMapG (CoreMapG (BndrMap b))
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((BndrMap a -> BndrMap b)
    -> CoreMapG (BndrMap a) -> CoreMapG (BndrMap b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> BndrMap a -> BndrMap b
    forall a b. (a -> b) -> BndrMap a -> BndrMap b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f)) CoreMapG (CoreMapG (BndrMap a))
    cletn, cm_letr :: ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap b))
    cm_letr = (CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap b))
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap b))
    forall a b.
    (a -> b)
    -> ListMap (GenMap CoreMapX) a -> ListMap (GenMap CoreMapX) b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((ListMap BndrMap a -> ListMap BndrMap b)
    -> CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> ListMap BndrMap a -> ListMap BndrMap b
    forall a b. (a -> b) -> ListMap BndrMap a -> ListMap BndrMap b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f)) ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cletr
          , cm_case :: CoreMapG (ListMap AltMap b)
    cm_case = (ListMap AltMap a -> ListMap AltMap b)
    -> CoreMapG (ListMap AltMap a) -> CoreMapG (ListMap AltMap b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> ListMap AltMap a -> ListMap AltMap b
    forall a b. (a -> b) -> ListMap AltMap a -> ListMap AltMap b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) CoreMapG (ListMap AltMap a)
    ccase, cm_ecase :: CoreMapG (TypeMapG b)
    cm_ecase = (TypeMapG a -> TypeMapG b)
    -> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> TypeMapG a -> TypeMapG b
    forall a b. (a -> b) -> GenMap TypeMapX a -> GenMap TypeMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) CoreMapG (TypeMapG a)
    cecase
          , cm_tick :: CoreMapG (TickishMap b)
    cm_tick = (TickishMap a -> TickishMap b)
    -> CoreMapG (TickishMap a) -> CoreMapG (TickishMap b)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> TickishMap a -> TickishMap b
    forall a b.
    (a -> b)
    -> Map (GenTickish 'TickishPassCore) a
    -> Map (GenTickish 'TickishPassCore) b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) CoreMapG (TickishMap a)
    ctick }

    instance TrieMap CoreMapX where
       type Key CoreMapX = DeBruijn CoreExpr
       emptyTM :: forall a. CoreMapX a
    emptyTM  = CoreMapX a
    forall a. CoreMapX a
    emptyE
       lookupTM :: forall b. Key CoreMapX -> CoreMapX b -> Maybe b
    lookupTM = Key CoreMapX -> CoreMapX b -> Maybe b
    DeBruijn (Expr Id) -> CoreMapX b -> Maybe b
    forall a. DeBruijn (Expr Id) -> CoreMapX a -> Maybe a
    lkE
       alterTM :: forall b. Key CoreMapX -> XT b -> CoreMapX b -> CoreMapX b
    alterTM  = Key CoreMapX -> (Maybe b -> Maybe b) -> CoreMapX b -> CoreMapX b
    DeBruijn (Expr Id)
    -> (Maybe b -> Maybe b) -> CoreMapX b -> CoreMapX b
    forall a. DeBruijn (Expr Id) -> XT a -> CoreMapX a -> CoreMapX a
    xtE
       foldTM :: forall a b. (a -> b -> b) -> CoreMapX a -> b -> b
    foldTM   = (a -> b -> b) -> CoreMapX a -> b -> b
    forall a b. (a -> b -> b) -> CoreMapX a -> b -> b
    fdE
       filterTM :: forall a. (a -> Bool) -> CoreMapX a -> CoreMapX a
    filterTM = (a -> Bool) -> CoreMapX a -> CoreMapX a
    forall a. (a -> Bool) -> CoreMapX a -> CoreMapX a
    ftE

    --------------------------
    ftE :: (a->Bool) -> CoreMapX a -> CoreMapX a
    ftE :: forall a. (a -> Bool) -> CoreMapX a -> CoreMapX a
    ftE a -> Bool
    f (CM { cm_var :: forall a. CoreMapX a -> VarMap a
    cm_var = VarMap a
    cvar, cm_lit :: forall a. CoreMapX a -> LiteralMap a
    cm_lit = LiteralMap a
    clit
              , cm_co :: forall a. CoreMapX a -> CoercionMapG a
    cm_co = CoercionMapG a
    cco, cm_type :: forall a. CoreMapX a -> TypeMapG a
    cm_type = TypeMapG a
    ctype
              , cm_cast :: forall a. CoreMapX a -> CoreMapG (CoercionMapG a)
    cm_cast = CoreMapG (CoercionMapG a)
    ccast , cm_app :: forall a. CoreMapX a -> CoreMapG (CoreMapG a)
    cm_app = CoreMapG (CoreMapG a)
    capp
              , cm_lam :: forall a. CoreMapX a -> CoreMapG (BndrMap a)
    cm_lam = CoreMapG (BndrMap a)
    clam, cm_letn :: forall a. CoreMapX a -> CoreMapG (CoreMapG (BndrMap a))
    cm_letn = CoreMapG (CoreMapG (BndrMap a))
    cletn
              , cm_letr :: forall a.
    CoreMapX a
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr = ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cletr, cm_case :: forall a. CoreMapX a -> CoreMapG (ListMap AltMap a)
    cm_case = CoreMapG (ListMap AltMap a)
    ccase
              , cm_ecase :: forall a. CoreMapX a -> CoreMapG (TypeMapG a)
    cm_ecase = CoreMapG (TypeMapG a)
    cecase, cm_tick :: forall a. CoreMapX a -> CoreMapG (TickishMap a)
    cm_tick = CoreMapG (TickishMap a)
    ctick })
      = CM { cm_var :: VarMap a
    cm_var = (a -> Bool) -> VarMap a -> VarMap a
    forall a. (a -> Bool) -> VarMap a -> VarMap a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f VarMap a
    cvar, cm_lit :: LiteralMap a
    cm_lit = (a -> Bool) -> LiteralMap a -> LiteralMap a
    forall a. (a -> Bool) -> Map Literal a -> Map Literal a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f LiteralMap a
    clit
           , cm_co :: CoercionMapG a
    cm_co = (a -> Bool) -> CoercionMapG a -> CoercionMapG a
    forall a.
    (a -> Bool) -> GenMap CoercionMapX a -> GenMap CoercionMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f CoercionMapG a
    cco, cm_type :: TypeMapG a
    cm_type = (a -> Bool) -> TypeMapG a -> TypeMapG a
    forall a. (a -> Bool) -> GenMap TypeMapX a -> GenMap TypeMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f TypeMapG a
    ctype
           , cm_cast :: CoreMapG (CoercionMapG a)
    cm_cast = (CoercionMapG a -> CoercionMapG a)
    -> CoreMapG (CoercionMapG a) -> CoreMapG (CoercionMapG a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> CoercionMapG a -> CoercionMapG a
    forall a.
    (a -> Bool) -> GenMap CoercionMapX a -> GenMap CoercionMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) CoreMapG (CoercionMapG a)
    ccast, cm_app :: CoreMapG (CoreMapG a)
    cm_app = (CoreMapG a -> CoreMapG a)
    -> CoreMapG (CoreMapG a) -> CoreMapG (CoreMapG a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> CoreMapG a -> CoreMapG a
    forall a. (a -> Bool) -> GenMap CoreMapX a -> GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) CoreMapG (CoreMapG a)
    capp
           , cm_lam :: CoreMapG (BndrMap a)
    cm_lam = (BndrMap a -> BndrMap a)
    -> CoreMapG (BndrMap a) -> CoreMapG (BndrMap a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> BndrMap a -> BndrMap a
    forall a. (a -> Bool) -> BndrMap a -> BndrMap a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) CoreMapG (BndrMap a)
    clam, cm_letn :: CoreMapG (CoreMapG (BndrMap a))
    cm_letn = (CoreMapG (BndrMap a) -> CoreMapG (BndrMap a))
    -> CoreMapG (CoreMapG (BndrMap a))
    -> CoreMapG (CoreMapG (BndrMap a))
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((BndrMap a -> BndrMap a)
    -> CoreMapG (BndrMap a) -> CoreMapG (BndrMap a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> BndrMap a -> BndrMap a
    forall a. (a -> Bool) -> BndrMap a -> BndrMap a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f)) CoreMapG (CoreMapG (BndrMap a))
    cletn
           , cm_letr :: ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr = (CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap a))
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    forall a b.
    (a -> b)
    -> ListMap (GenMap CoreMapX) a -> ListMap (GenMap CoreMapX) b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((ListMap BndrMap a -> ListMap BndrMap a)
    -> CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> ListMap BndrMap a -> ListMap BndrMap a
    forall a. (a -> Bool) -> ListMap BndrMap a -> ListMap BndrMap a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f)) ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cletr, cm_case :: CoreMapG (ListMap AltMap a)
    cm_case = (ListMap AltMap a -> ListMap AltMap a)
    -> CoreMapG (ListMap AltMap a) -> CoreMapG (ListMap AltMap a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> ListMap AltMap a -> ListMap AltMap a
    forall a. (a -> Bool) -> ListMap AltMap a -> ListMap AltMap a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) CoreMapG (ListMap AltMap a)
    ccase
           , cm_ecase :: CoreMapG (TypeMapG a)
    cm_ecase = (TypeMapG a -> TypeMapG a)
    -> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> TypeMapG a -> TypeMapG a
    forall a. (a -> Bool) -> GenMap TypeMapX a -> GenMap TypeMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) CoreMapG (TypeMapG a)
    cecase, cm_tick :: CoreMapG (TickishMap a)
    cm_tick = (TickishMap a -> TickishMap a)
    -> CoreMapG (TickishMap a) -> CoreMapG (TickishMap a)
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> TickishMap a -> TickishMap a
    forall a.
    (a -> Bool)
    -> Map (GenTickish 'TickishPassCore) a
    -> Map (GenTickish 'TickishPassCore) a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) CoreMapG (TickishMap a)
    ctick }

    --------------------------
    lookupCoreMap :: CoreMap a -> CoreExpr -> Maybe a
    lookupCoreMap :: forall a. CoreMap a -> Expr Id -> Maybe a
    lookupCoreMap CoreMap a
    cm Expr Id
    e = Key CoreMap -> CoreMap a -> Maybe a
    forall b. Key CoreMap -> CoreMap b -> Maybe b
    forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
    lookupTM Expr Id
    Key CoreMap
    e CoreMap a
    cm

    extendCoreMap :: CoreMap a -> CoreExpr -> a -> CoreMap a
    extendCoreMap :: forall a. CoreMap a -> Expr Id -> a -> CoreMap a
    extendCoreMap CoreMap a
    m Expr Id
    e a
    v = Key CoreMap -> XT a -> CoreMap a -> CoreMap a
    forall b. Key CoreMap -> XT b -> CoreMap b -> CoreMap b
    forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
    alterTM Expr Id
    Key CoreMap
    e (\Maybe a
    _ -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    v) CoreMap a
    m

    foldCoreMap :: (a -> b -> b) -> b -> CoreMap a -> b
    foldCoreMap :: forall a b. (a -> b -> b) -> b -> CoreMap a -> b
    foldCoreMap a -> b -> b
    k b
    z CoreMap a
    m = (a -> b -> b) -> CoreMap a -> b -> b
    forall a b. (a -> b -> b) -> CoreMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k CoreMap a
    m b
    z

    emptyCoreMap :: CoreMap a
    emptyCoreMap :: forall a. CoreMap a
    emptyCoreMap = CoreMap a
    forall a. CoreMap a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM

    instance Outputable a => Outputable (CoreMap a) where
      ppr :: CoreMap a -> SDoc
    ppr CoreMap a
    m = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "CoreMap elts" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> [a] -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr ((a -> [a] -> [a]) -> CoreMap a -> [a] -> [a]
    forall a b. (a -> b -> b) -> CoreMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM (:) CoreMap a
    m [])

    -------------------------
    fdE :: (a -> b -> b) -> CoreMapX a -> b -> b
    fdE :: forall a b. (a -> b -> b) -> CoreMapX a -> b -> b
    fdE a -> b -> b
    k CoreMapX a
    m
      = (a -> b -> b) -> VarMap a -> b -> b
    forall a b. (a -> b -> b) -> VarMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k (CoreMapX a -> VarMap a
    forall a. CoreMapX a -> VarMap a
    cm_var CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b -> b) -> Map Literal a -> b -> b
    forall a b. (a -> b -> b) -> Map Literal a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k (CoreMapX a -> Map Literal a
    forall a. CoreMapX a -> LiteralMap a
    cm_lit CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b -> b) -> GenMap CoercionMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoercionMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k (CoreMapX a -> GenMap CoercionMapX a
    forall a. CoreMapX a -> CoercionMapG a
    cm_co CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b -> b) -> GenMap TypeMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap TypeMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k (CoreMapX a -> GenMap TypeMapX a
    forall a. CoreMapX a -> TypeMapG a
    cm_type CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap CoercionMapX a -> b -> b)
    -> GenMap CoreMapX (GenMap CoercionMapX a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> GenMap CoercionMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoercionMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (CoreMapX a -> GenMap CoreMapX (GenMap CoercionMapX a)
    forall a. CoreMapX a -> CoreMapG (CoercionMapG a)
    cm_cast CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Map (GenTickish 'TickishPassCore) a -> b -> b)
    -> GenMap CoreMapX (Map (GenTickish 'TickishPassCore) a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> Map (GenTickish 'TickishPassCore) a -> b -> b
    forall a b.
    (a -> b -> b) -> Map (GenTickish 'TickishPassCore) a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (CoreMapX a -> GenMap CoreMapX (Map (GenTickish 'TickishPassCore) a)
    forall a. CoreMapX a -> CoreMapG (TickishMap a)
    cm_tick CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap CoreMapX a -> b -> b)
    -> GenMap CoreMapX (GenMap CoreMapX a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (CoreMapX a -> GenMap CoreMapX (GenMap CoreMapX a)
    forall a. CoreMapX a -> CoreMapG (CoreMapG a)
    cm_app CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (BndrMap a -> b -> b) -> GenMap CoreMapX (BndrMap a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> BndrMap a -> b -> b
    forall a b. (a -> b -> b) -> BndrMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (CoreMapX a -> GenMap CoreMapX (BndrMap a)
    forall a. CoreMapX a -> CoreMapG (BndrMap a)
    cm_lam CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap CoreMapX (BndrMap a) -> b -> b)
    -> GenMap CoreMapX (GenMap CoreMapX (BndrMap a)) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((BndrMap a -> b -> b) -> GenMap CoreMapX (BndrMap a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> BndrMap a -> b -> b
    forall a b. (a -> b -> b) -> BndrMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k)) (CoreMapX a -> GenMap CoreMapX (GenMap CoreMapX (BndrMap a))
    forall a. CoreMapX a -> CoreMapG (CoreMapG (BndrMap a))
    cm_letn CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap CoreMapX (ListMap BndrMap a) -> b -> b)
    -> ListMap (GenMap CoreMapX) (GenMap CoreMapX (ListMap BndrMap a))
    -> b
    -> b
    forall a b. (a -> b -> b) -> ListMap (GenMap CoreMapX) a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((ListMap BndrMap a -> b -> b)
    -> GenMap CoreMapX (ListMap BndrMap a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> ListMap BndrMap a -> b -> b
    forall a b. (a -> b -> b) -> ListMap BndrMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k)) (CoreMapX a
    -> ListMap (GenMap CoreMapX) (GenMap CoreMapX (ListMap BndrMap a))
    forall a.
    CoreMapX a
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ListMap AltMap a -> b -> b)
    -> GenMap CoreMapX (ListMap AltMap a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> ListMap AltMap a -> b -> b
    forall a b. (a -> b -> b) -> ListMap AltMap a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (CoreMapX a -> GenMap CoreMapX (ListMap AltMap a)
    forall a. CoreMapX a -> CoreMapG (ListMap AltMap a)
    cm_case CoreMapX a
    m)
      (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap TypeMapX a -> b -> b)
    -> GenMap CoreMapX (GenMap TypeMapX a) -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> GenMap TypeMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap TypeMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (CoreMapX a -> GenMap CoreMapX (GenMap TypeMapX a)
    forall a. CoreMapX a -> CoreMapG (TypeMapG a)
    cm_ecase CoreMapX a
    m)

    -- lkE: lookup in trie for expressions
    lkE :: DeBruijn CoreExpr -> CoreMapX a -> Maybe a
    lkE :: forall a. DeBruijn (Expr Id) -> CoreMapX a -> Maybe a
    lkE (D CmEnv
    env Expr Id
    expr) CoreMapX a
    cm = Expr Id -> CoreMapX a -> Maybe a
    go Expr Id
    expr CoreMapX a
    cm
      where
        go :: Expr Id -> CoreMapX a -> Maybe a
    go (Var Id
    v)              = CoreMapX a -> VarMap a
    forall a. CoreMapX a -> VarMap a
    cm_var  (CoreMapX a -> VarMap a)
    -> (VarMap a -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> CmEnv -> Id -> VarMap a -> Maybe a
    forall a. CmEnv -> Id -> VarMap a -> Maybe a
    lkVar CmEnv
    env Id
    v
        go (Lit Literal
    l)              = CoreMapX a -> LiteralMap a
    forall a. CoreMapX a -> LiteralMap a
    cm_lit  (CoreMapX a -> LiteralMap a)
    -> (LiteralMap a -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key (Map Literal) -> LiteralMap a -> Maybe a
    forall b. Key (Map Literal) -> Map Literal b -> Maybe b
    forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
    lookupTM Key (Map Literal)
    Literal
    l
        go (Type Mult
    t)             = CoreMapX a -> TypeMapG a
    forall a. CoreMapX a -> TypeMapG a
    cm_type (CoreMapX a -> TypeMapG a)
    -> (TypeMapG a -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key TypeMapX -> TypeMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Mult
    t)
        go (Coercion CoercionR
    c)         = CoreMapX a -> CoercionMapG a
    forall a. CoreMapX a -> CoercionMapG a
    cm_co   (CoreMapX a -> CoercionMapG a)
    -> (CoercionMapG a -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoercionMapX -> CoercionMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> CoercionR -> DeBruijn CoercionR
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env CoercionR
    c)
        go (Cast Expr Id
    e CoercionR
    c)           = CoreMapX a -> CoreMapG (CoercionMapG a)
    forall a. CoreMapX a -> CoreMapG (CoercionMapG a)
    cm_cast (CoreMapX a -> CoreMapG (CoercionMapG a))
    -> (CoreMapG (CoercionMapG a) -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX -> CoreMapG (CoercionMapG a) -> Maybe (CoercionMapG a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    e) (CoreMapG (CoercionMapG a) -> Maybe (CoercionMapG a))
    -> (CoercionMapG a -> Maybe a)
    -> CoreMapG (CoercionMapG a)
    -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key CoercionMapX -> CoercionMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> CoercionR -> DeBruijn CoercionR
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env CoercionR
    c)
        go (Tick GenTickish 'TickishPassCore
    tickish Expr Id
    e)     = CoreMapX a -> CoreMapG (TickishMap a)
    forall a. CoreMapX a -> CoreMapG (TickishMap a)
    cm_tick (CoreMapX a -> CoreMapG (TickishMap a))
    -> (CoreMapG (TickishMap a) -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX -> CoreMapG (TickishMap a) -> Maybe (TickishMap a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    e) (CoreMapG (TickishMap a) -> Maybe (TickishMap a))
    -> (TickishMap a -> Maybe a) -> CoreMapG (TickishMap a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> GenTickish 'TickishPassCore -> TickishMap a -> Maybe a
    forall a. GenTickish 'TickishPassCore -> TickishMap a -> Maybe a
    lkTickish GenTickish 'TickishPassCore
    tickish
        go (App Expr Id
    e1 Expr Id
    e2)          = CoreMapX a -> CoreMapG (CoreMapG a)
    forall a. CoreMapX a -> CoreMapG (CoreMapG a)
    cm_app  (CoreMapX a -> CoreMapG (CoreMapG a))
    -> (CoreMapG (CoreMapG a) -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX -> CoreMapG (CoreMapG a) -> Maybe (CoreMapG a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    e2) (CoreMapG (CoreMapG a) -> Maybe (CoreMapG a))
    -> (CoreMapG a -> Maybe a) -> CoreMapG (CoreMapG a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key CoreMapX -> CoreMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    e1)
        go (Lam Id
    v Expr Id
    e)            = CoreMapX a -> CoreMapG (BndrMap a)
    forall a. CoreMapX a -> CoreMapG (BndrMap a)
    cm_lam  (CoreMapX a -> CoreMapG (BndrMap a))
    -> (CoreMapG (BndrMap a) -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX -> CoreMapG (BndrMap a) -> Maybe (BndrMap a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env Id
    v) Expr Id
    e)
                                  (CoreMapG (BndrMap a) -> Maybe (BndrMap a))
    -> (BndrMap a -> Maybe a) -> CoreMapG (BndrMap a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> CmEnv -> Id -> BndrMap a -> Maybe a
    forall a. CmEnv -> Id -> BndrMap a -> Maybe a
    lkBndr CmEnv
    env Id
    v
        go (Let (NonRec Id
    b Expr Id
    r) Expr Id
    e) = CoreMapX a -> CoreMapG (CoreMapG (BndrMap a))
    forall a. CoreMapX a -> CoreMapG (CoreMapG (BndrMap a))
    cm_letn (CoreMapX a -> CoreMapG (CoreMapG (BndrMap a)))
    -> (CoreMapG (CoreMapG (BndrMap a)) -> Maybe a)
    -> CoreMapX a
    -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX
    -> CoreMapG (CoreMapG (BndrMap a)) -> Maybe (CoreMapG (BndrMap a))
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    r)
                                  (CoreMapG (CoreMapG (BndrMap a)) -> Maybe (CoreMapG (BndrMap a)))
    -> (CoreMapG (BndrMap a) -> Maybe a)
    -> CoreMapG (CoreMapG (BndrMap a))
    -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key CoreMapX -> CoreMapG (BndrMap a) -> Maybe (BndrMap a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env Id
    b) Expr Id
    e) (CoreMapG (BndrMap a) -> Maybe (BndrMap a))
    -> (BndrMap a -> Maybe a) -> CoreMapG (BndrMap a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> CmEnv -> Id -> BndrMap a -> Maybe a
    forall a. CmEnv -> Id -> BndrMap a -> Maybe a
    lkBndr CmEnv
    env Id
    b
        go (Let (Rec [(Id, Expr Id)]
    prs) Expr Id
    e)    = let ([Id]
    bndrs,[Expr Id]
    rhss) = [(Id, Expr Id)] -> ([Id], [Expr Id])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [(Id, Expr Id)]
    prs
                                      env1 :: CmEnv
    env1 = CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env [Id]
    bndrs
                                  in CoreMapX a
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    forall a.
    CoreMapX a
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    cm_letr
                                     (CoreMapX a
     -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a)))
    -> (ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
        -> Maybe a)
    -> CoreMapX a
    -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> (forall b. Expr Id -> CoreMapG b -> Maybe b)
    -> [Expr Id]
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    -> Maybe (CoreMapG (ListMap BndrMap a))
    forall (m :: * -> *) k a.
    TrieMap m =>
    (forall b. k -> m b -> Maybe b) -> [k] -> ListMap m a -> Maybe a
    lkList (Key CoreMapX -> GenMap CoreMapX b -> Maybe b
    DeBruijn (Expr Id) -> GenMap CoreMapX b -> Maybe b
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (DeBruijn (Expr Id) -> GenMap CoreMapX b -> Maybe b)
    -> (Expr Id -> DeBruijn (Expr Id))
    -> Expr Id
    -> GenMap CoreMapX b
    -> Maybe b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1) [Expr Id]
    rhss
                                     (ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
     -> Maybe (CoreMapG (ListMap BndrMap a)))
    -> (CoreMapG (ListMap BndrMap a) -> Maybe a)
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key CoreMapX
    -> CoreMapG (ListMap BndrMap a) -> Maybe (ListMap BndrMap a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 Expr Id
    e)
                                     (CoreMapG (ListMap BndrMap a) -> Maybe (ListMap BndrMap a))
    -> (ListMap BndrMap a -> Maybe a)
    -> CoreMapG (ListMap BndrMap a)
    -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> (forall b. Id -> BndrMap b -> Maybe b)
    -> [Id] -> ListMap BndrMap a -> Maybe a
    forall (m :: * -> *) k a.
    TrieMap m =>
    (forall b. k -> m b -> Maybe b) -> [k] -> ListMap m a -> Maybe a
    lkList (CmEnv -> Id -> BndrMap b -> Maybe b
    forall a. CmEnv -> Id -> BndrMap a -> Maybe a
    lkBndr CmEnv
    env1) [Id]
    bndrs
        go (Case Expr Id
    e Id
    b Mult
    ty [Alt Id]
    as)     -- See Note [Empty case alternatives]
                   | [Alt Id] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Alt Id]
    as    = CoreMapX a -> CoreMapG (TypeMapG a)
    forall a. CoreMapX a -> CoreMapG (TypeMapG a)
    cm_ecase (CoreMapX a -> CoreMapG (TypeMapG a))
    -> (CoreMapG (TypeMapG a) -> Maybe a) -> CoreMapX a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX -> CoreMapG (TypeMapG a) -> Maybe (TypeMapG a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    e) (CoreMapG (TypeMapG a) -> Maybe (TypeMapG a))
    -> (TypeMapG a -> Maybe a) -> CoreMapG (TypeMapG a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key TypeMapX -> TypeMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Mult -> DeBruijn Mult
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Mult
    ty)
                   | Bool
    otherwise  = CoreMapX a -> CoreMapG (ListMap AltMap a)
    forall a. CoreMapX a -> CoreMapG (ListMap AltMap a)
    cm_case (CoreMapX a -> CoreMapG (ListMap AltMap a))
    -> (CoreMapG (ListMap AltMap a) -> Maybe a)
    -> CoreMapX a
    -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX
    -> CoreMapG (ListMap AltMap a) -> Maybe (ListMap AltMap a)
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    e)
                                  (CoreMapG (ListMap AltMap a) -> Maybe (ListMap AltMap a))
    -> (ListMap AltMap a -> Maybe a)
    -> CoreMapG (ListMap AltMap a)
    -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> (forall b. Alt Id -> AltMap b -> Maybe b)
    -> [Alt Id] -> ListMap AltMap a -> Maybe a
    forall (m :: * -> *) k a.
    TrieMap m =>
    (forall b. k -> m b -> Maybe b) -> [k] -> ListMap m a -> Maybe a
    lkList (CmEnv -> Alt Id -> AltMap b -> Maybe b
    forall a. CmEnv -> Alt Id -> AltMap a -> Maybe a
    lkA (CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env Id
    b)) [Alt Id]
    as

    xtE :: DeBruijn CoreExpr -> XT a -> CoreMapX a -> CoreMapX a
    xtE :: forall a. DeBruijn (Expr Id) -> XT a -> CoreMapX a -> CoreMapX a
    xtE (D CmEnv
    env (Var Id
    v))              XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_var  = cm_var m
                                                     |> xtVar env v f }
    xtE (D CmEnv
    env (Type Mult
    t))             XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_type = cm_type m
                                                     |> xtG (D env t) f }
    xtE (D CmEnv
    env (Coercion CoercionR
    c))         XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_co   = cm_co m
                                                     |> xtG (D env c) f }
    xtE (D CmEnv
    _   (Lit Literal
    l))              XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_lit  = cm_lit m  |> alterTM l f }
    xtE (D CmEnv
    env (Cast Expr Id
    e CoercionR
    c))           XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_cast = cm_cast m |> xtG (D env e)
                                                     |>> xtG (D env c) f }
    xtE (D CmEnv
    env (Tick GenTickish 'TickishPassCore
    t Expr Id
    e))           XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_tick = cm_tick m |> xtG (D env e)
                                                     |>> xtTickish t f }
    xtE (D CmEnv
    env (App Expr Id
    e1 Expr Id
    e2))          XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_app = cm_app m |> xtG (D env e2)
                                                     |>> xtG (D env e1) f }
    xtE (D CmEnv
    env (Lam Id
    v Expr Id
    e))            XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_lam = cm_lam m
                                                     |> xtG (D (extendCME env v) e)
                                                     |>> xtBndr env v f }
    xtE (D CmEnv
    env (Let (NonRec Id
    b Expr Id
    r) Expr Id
    e)) XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_letn = cm_letn m
                                                     |> xtG (D (extendCME env b) e)
                                                     |>> xtG (D env r)
                                                     |>> xtBndr env b f }
    xtE (D CmEnv
    env (Let (Rec [(Id, Expr Id)]
    prs) Expr Id
    e))    XT a
    f CoreMapX a
    m = CoreMapX a
    m { cm_letr =
                                                  let (bndrs,rhss) = unzip prs
                                                      env1 = CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env [Id]
    bndrs
                                                  in cm_letr m
                                                     |>  xtList (xtG . D env1) rhss
                                                     |>> xtG (D env1 e)
                                                     |>> xtList (xtBndr env1)
                                                                bndrs f }
    xtE (D CmEnv
    env (Case Expr Id
    e Id
    b Mult
    ty [Alt Id]
    as))     XT a
    f CoreMapX a
    m
                         | [Alt Id] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Alt Id]
    as   = CoreMapX a
    m { cm_ecase = cm_ecase m |> xtG (D env e)
                                                     |>> xtG (D env ty) f }
                         | Bool
    otherwise = CoreMapX a
    m { cm_case = cm_case m |> xtG (D env e)
                                                     |>> let env1 = CmEnv -> Id -> CmEnv
    extendCME CmEnv
    env Id
    b
                                                         in xtList (xtA env1) as f }

    -- TODO: this seems a bit dodgy, see 'eqTickish'
    type TickishMap a = Map.Map CoreTickish a
    lkTickish :: CoreTickish -> TickishMap a -> Maybe a
    lkTickish :: forall a. GenTickish 'TickishPassCore -> TickishMap a -> Maybe a
    lkTickish = Key (Map (GenTickish 'TickishPassCore))
    -> Map (GenTickish 'TickishPassCore) a -> Maybe a
    GenTickish 'TickishPassCore
    -> Map (GenTickish 'TickishPassCore) a -> Maybe a
    forall b.
    Key (Map (GenTickish 'TickishPassCore))
    -> Map (GenTickish 'TickishPassCore) b -> Maybe b
    forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
    lookupTM

    xtTickish :: CoreTickish -> XT a -> TickishMap a -> TickishMap a
    xtTickish :: forall a.
    GenTickish 'TickishPassCore -> XT a -> TickishMap a -> TickishMap a
    xtTickish = Key (Map (GenTickish 'TickishPassCore))
    -> XT a
    -> Map (GenTickish 'TickishPassCore) a
    -> Map (GenTickish 'TickishPassCore) a
    GenTickish 'TickishPassCore
    -> XT a
    -> Map (GenTickish 'TickishPassCore) a
    -> Map (GenTickish 'TickishPassCore) a
    forall b.
    Key (Map (GenTickish 'TickishPassCore))
    -> XT b
    -> Map (GenTickish 'TickishPassCore) b
    -> Map (GenTickish 'TickishPassCore) b
    forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
    alterTM

    ------------------------
    data AltMap a   -- A single alternative
      = AM { forall a. AltMap a -> CoreMapG a
    am_deflt :: CoreMapG a
           , forall a. AltMap a -> DNameEnv (CoreMapG a)
    am_data  :: DNameEnv (CoreMapG a)
           , forall a. AltMap a -> LiteralMap (CoreMapG a)
    am_lit   :: LiteralMap (CoreMapG a) }

    -- TODO(22292): derive
    instance Functor AltMap where
        fmap :: forall a b. (a -> b) -> AltMap a -> AltMap b
    fmap a -> b
    f AM { am_deflt :: forall a. AltMap a -> CoreMapG a
    am_deflt = CoreMapG a
    adeflt, am_data :: forall a. AltMap a -> DNameEnv (CoreMapG a)
    am_data = DNameEnv (CoreMapG a)
    adata, am_lit :: forall a. AltMap a -> LiteralMap (CoreMapG a)
    am_lit = LiteralMap (CoreMapG a)
    alit } = AM
          { am_deflt :: CoreMapG b
    am_deflt = (a -> b) -> CoreMapG a -> CoreMapG b
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f CoreMapG a
    adeflt, am_data :: DNameEnv (CoreMapG b)
    am_data = (CoreMapG a -> CoreMapG b)
    -> DNameEnv (CoreMapG a) -> DNameEnv (CoreMapG b)
    forall a b. (a -> b) -> UniqDFM Name a -> UniqDFM Name b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> CoreMapG a -> CoreMapG b
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) DNameEnv (CoreMapG a)
    adata, am_lit :: LiteralMap (CoreMapG b)
    am_lit = (CoreMapG a -> CoreMapG b)
    -> LiteralMap (CoreMapG a) -> LiteralMap (CoreMapG b)
    forall a b. (a -> b) -> Map Literal a -> Map Literal b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> b) -> CoreMapG a -> CoreMapG b
    forall a b. (a -> b) -> GenMap CoreMapX a -> GenMap CoreMapX b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) LiteralMap (CoreMapG a)
    alit }

    instance TrieMap AltMap where
       type Key AltMap = CoreAlt
       emptyTM :: forall a. AltMap a
    emptyTM  = AM { am_deflt :: CoreMapG a
    am_deflt = CoreMapG a
    forall a. GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM
                     , am_data :: DNameEnv (CoreMapG a)
    am_data = DNameEnv (CoreMapG a)
    forall a. DNameEnv a
    emptyDNameEnv
                     , am_lit :: LiteralMap (CoreMapG a)
    am_lit  = LiteralMap (CoreMapG a)
    forall a. Map Literal a
    forall (m :: * -> *) a. TrieMap m => m a
    emptyTM }
       lookupTM :: forall b. Key AltMap -> AltMap b -> Maybe b
    lookupTM = CmEnv -> Alt Id -> AltMap b -> Maybe b
    forall a. CmEnv -> Alt Id -> AltMap a -> Maybe a
    lkA CmEnv
    emptyCME
       alterTM :: forall b. Key AltMap -> XT b -> AltMap b -> AltMap b
    alterTM  = CmEnv -> Alt Id -> (Maybe b -> Maybe b) -> AltMap b -> AltMap b
    forall a. CmEnv -> Alt Id -> XT a -> AltMap a -> AltMap a
    xtA CmEnv
    emptyCME
       foldTM :: forall a b. (a -> b -> b) -> AltMap a -> b -> b
    foldTM   = (a -> b -> b) -> AltMap a -> b -> b
    forall a b. (a -> b -> b) -> AltMap a -> b -> b
    fdA
       filterTM :: forall a. (a -> Bool) -> AltMap a -> AltMap a
    filterTM = (a -> Bool) -> AltMap a -> AltMap a
    forall a. (a -> Bool) -> AltMap a -> AltMap a
    ftA

    instance Eq (DeBruijn CoreAlt) where
      D CmEnv
    env1 Alt Id
    a1 == :: DeBruijn (Alt Id) -> DeBruijn (Alt Id) -> Bool
    == D CmEnv
    env2 Alt Id
    a2 = Alt Id -> Alt Id -> Bool
    go Alt Id
    a1 Alt Id
    a2 where
        go :: Alt Id -> Alt Id -> Bool
    go (Alt AltCon
    DEFAULT [Id]
    _ Expr Id
    rhs1) (Alt AltCon
    DEFAULT [Id]
    _ Expr Id
    rhs2)
            = CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 Expr Id
    rhs1 DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 Expr Id
    rhs2
        go (Alt (LitAlt Literal
    lit1) [Id]
    _ Expr Id
    rhs1) (Alt (LitAlt Literal
    lit2) [Id]
    _ Expr Id
    rhs2)
            = Literal
    lit1 Literal -> Literal -> Bool
    forall a. Eq a => a -> a -> Bool
    == Literal
    lit2 Bool -> Bool -> Bool
    && CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env1 Expr Id
    rhs1 DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env2 Expr Id
    rhs2
        go (Alt (DataAlt DataCon
    dc1) [Id]
    bs1 Expr Id
    rhs1) (Alt (DataAlt DataCon
    dc2) [Id]
    bs2 Expr Id
    rhs2)
            = DataCon
    dc1 DataCon -> DataCon -> Bool
    forall a. Eq a => a -> a -> Bool
    == DataCon
    dc2 Bool -> Bool -> Bool
    &&
              CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env1 [Id]
    bs1) Expr Id
    rhs1 DeBruijn (Expr Id) -> DeBruijn (Expr Id) -> Bool
    forall a. Eq a => a -> a -> Bool
    == CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env2 [Id]
    bs2) Expr Id
    rhs2
        go Alt Id
    _ Alt Id
    _ = Bool
    False

    ftA :: (a->Bool) -> AltMap a -> AltMap a
    ftA :: forall a. (a -> Bool) -> AltMap a -> AltMap a
    ftA a -> Bool
    f (AM { am_deflt :: forall a. AltMap a -> CoreMapG a
    am_deflt = CoreMapG a
    adeflt, am_data :: forall a. AltMap a -> DNameEnv (CoreMapG a)
    am_data = DNameEnv (CoreMapG a)
    adata, am_lit :: forall a. AltMap a -> LiteralMap (CoreMapG a)
    am_lit = LiteralMap (CoreMapG a)
    alit })
      = AM { am_deflt :: CoreMapG a
    am_deflt = (a -> Bool) -> CoreMapG a -> CoreMapG a
    forall a. (a -> Bool) -> GenMap CoreMapX a -> GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f CoreMapG a
    adeflt
           , am_data :: DNameEnv (CoreMapG a)
    am_data = (CoreMapG a -> CoreMapG a)
    -> DNameEnv (CoreMapG a) -> DNameEnv (CoreMapG a)
    forall a b. (a -> b) -> UniqDFM Name a -> UniqDFM Name b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> CoreMapG a -> CoreMapG a
    forall a. (a -> Bool) -> GenMap CoreMapX a -> GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) DNameEnv (CoreMapG a)
    adata
           , am_lit :: LiteralMap (CoreMapG a)
    am_lit = (CoreMapG a -> CoreMapG a)
    -> LiteralMap (CoreMapG a) -> LiteralMap (CoreMapG a)
    forall a b. (a -> b) -> Map Literal a -> Map Literal b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> Bool) -> CoreMapG a -> CoreMapG a
    forall a. (a -> Bool) -> GenMap CoreMapX a -> GenMap CoreMapX a
    forall (m :: * -> *) a. TrieMap m => (a -> Bool) -> m a -> m a
    filterTM a -> Bool
    f) LiteralMap (CoreMapG a)
    alit }

    lkA :: CmEnv -> CoreAlt -> AltMap a -> Maybe a
    lkA :: forall a. CmEnv -> Alt Id -> AltMap a -> Maybe a
    lkA CmEnv
    env (Alt AltCon
    DEFAULT      [Id]
    _  Expr Id
    rhs) = AltMap a -> CoreMapG a
    forall a. AltMap a -> CoreMapG a
    am_deflt (AltMap a -> CoreMapG a)
    -> (CoreMapG a -> Maybe a) -> AltMap a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key CoreMapX -> CoreMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    rhs)
    lkA CmEnv
    env (Alt (LitAlt Literal
    lit) [Id]
    _  Expr Id
    rhs) = AltMap a -> LiteralMap (CoreMapG a)
    forall a. AltMap a -> LiteralMap (CoreMapG a)
    am_lit (AltMap a -> LiteralMap (CoreMapG a))
    -> (LiteralMap (CoreMapG a) -> Maybe a) -> AltMap a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> Key (Map Literal) -> LiteralMap (CoreMapG a) -> Maybe (CoreMapG a)
    forall b. Key (Map Literal) -> Map Literal b -> Maybe b
    forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
    lookupTM Key (Map Literal)
    Literal
    lit (LiteralMap (CoreMapG a) -> Maybe (CoreMapG a))
    -> (CoreMapG a -> Maybe a) -> LiteralMap (CoreMapG a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key CoreMapX -> CoreMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D CmEnv
    env Expr Id
    rhs)
    lkA CmEnv
    env (Alt (DataAlt DataCon
    dc) [Id]
    bs Expr Id
    rhs) = AltMap a -> DNameEnv (CoreMapG a)
    forall a. AltMap a -> DNameEnv (CoreMapG a)
    am_data (AltMap a -> DNameEnv (CoreMapG a))
    -> (DNameEnv (CoreMapG a) -> Maybe a) -> AltMap a -> Maybe a
    forall a b c. (a -> b) -> (b -> c) -> a -> c
    >.> DataCon -> DNameEnv (CoreMapG a) -> Maybe (CoreMapG a)
    forall n a. NamedThing n => n -> DNameEnv a -> Maybe a
    lkDNamed DataCon
    dc
                                            (DNameEnv (CoreMapG a) -> Maybe (CoreMapG a))
    -> (CoreMapG a -> Maybe a) -> DNameEnv (CoreMapG a) -> Maybe a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> Key CoreMapX -> CoreMapG a -> Maybe a
    forall (m :: * -> *) a.
    (Eq (Key m), TrieMap m) =>
    Key m -> GenMap m a -> Maybe a
    lkG (CmEnv -> Expr Id -> DeBruijn (Expr Id)
    forall a. CmEnv -> a -> DeBruijn a
    D (CmEnv -> [Id] -> CmEnv
    extendCMEs CmEnv
    env [Id]
    bs) Expr Id
    rhs)

    xtA :: CmEnv -> CoreAlt -> XT a -> AltMap a -> AltMap a
    xtA :: forall a. CmEnv -> Alt Id -> XT a -> AltMap a -> AltMap a
    xtA CmEnv
    env (Alt AltCon
    DEFAULT [Id]
    _ Expr Id
    rhs)      XT a
    f AltMap a
    m =
        AltMap a
    m { am_deflt = am_deflt m |> xtG (D env rhs) f }
    xtA CmEnv
    env (Alt (LitAlt Literal
    l) [Id]
    _ Expr Id
    rhs)   XT a
    f AltMap a
    m =
        AltMap a
    m { am_lit   = am_lit m   |> alterTM l |>> xtG (D env rhs) f }
    xtA CmEnv
    env (Alt (DataAlt DataCon
    d) [Id]
    bs Expr Id
    rhs) XT a
    f AltMap a
    m =
        AltMap a
    m { am_data  = am_data m  |> xtDNamed d
                                 |>> xtG (D (extendCMEs env bs) rhs) f }

    fdA :: (a -> b -> b) -> AltMap a -> b -> b
    fdA :: forall a b. (a -> b -> b) -> AltMap a -> b -> b
    fdA a -> b -> b
    k AltMap a
    m = (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k (AltMap a -> GenMap CoreMapX a
    forall a. AltMap a -> CoreMapG a
    am_deflt AltMap a
    m)
            (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap CoreMapX a -> b -> b)
    -> UniqDFM Name (GenMap CoreMapX a) -> b -> b
    forall a b. (a -> b -> b) -> UniqDFM Name a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (AltMap a -> UniqDFM Name (GenMap CoreMapX a)
    forall a. AltMap a -> DNameEnv (CoreMapG a)
    am_data AltMap a
    m)
            (b -> b) -> (b -> b) -> b -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (GenMap CoreMapX a -> b -> b)
    -> Map Literal (GenMap CoreMapX a) -> b -> b
    forall a b. (a -> b -> b) -> Map Literal a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM ((a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall a b. (a -> b -> b) -> GenMap CoreMapX a -> b -> b
    forall (m :: * -> *) a b.
    TrieMap m =>
    (a -> b -> b) -> m a -> b -> b
    foldTM a -> b -> b
    k) (AltMap a -> Map Literal (GenMap CoreMapX a)
    forall a. AltMap a -> LiteralMap (CoreMapG a)
    am_lit AltMap a
    m)