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

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module CoreMap(
   -- * Maps over Core expressions
   CoreMap, emptyCoreMap, extendCoreMap, lookupCoreMap, foldCoreMap,
   -- * Maps over 'Type's
   TypeMap, emptyTypeMap, extendTypeMap, lookupTypeMap, foldTypeMap,
   LooseTypeMap,
   -- ** With explicit scoping
   CmEnv, lookupCME, extendTypeMapWithScope, lookupTypeMapWithScope,
   mkDeBruijnContext,
   -- * Maps over 'Maybe' values
   MaybeMap,
   -- * Maps over 'List' values
   ListMap,
   -- * Maps over 'Literal's
   LiteralMap,
   -- * Map for compressing leaves. See Note [Compressed TrieMap]
   GenMap,
   -- * 'TrieMap' class
   TrieMap(..), insertTM, deleteTM,
   lkDFreeVar, xtDFreeVar,
   lkDNamed, xtDNamed,
   (>.>), (|>), (|>>),
 ) where

import GhcPrelude

import TrieMap
import CoreSyn
import Coercion
import Name
import Type
import TyCoRep
import Var
import FastString(FastString)
import Util

import qualified Data.Map    as Map
import qualified Data.IntMap as IntMap
import VarEnv
import NameEnv
import Outputable
import Control.Monad( (>=>) )

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

-- NB: Be careful about RULES and type families (#5821).  So we should make sure
-- to specify @Key TypeMapX@ (and not @DeBruijn Type@, the reduced form)

-- 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 TypeMapX     -> TypeMapG a     -> Maybe a #-}
{-# SPECIALIZE lkG :: Key CoercionMapX -> CoercionMapG a -> Maybe a #-}
{-# SPECIALIZE lkG :: Key CoreMapX     -> CoreMapG a     -> Maybe a #-}


{-# SPECIALIZE xtG :: Key TypeMapX     -> XT a -> TypeMapG a -> TypeMapG a #-}
{-# SPECIALIZE xtG :: Key CoercionMapX -> XT a -> CoercionMapG a -> CoercionMapG a #-}
{-# SPECIALIZE xtG :: Key CoreMapX     -> XT a -> CoreMapG a -> CoreMapG a #-}

{-# SPECIALIZE mapG :: (a -> b) -> TypeMapG a     -> TypeMapG b #-}
{-# SPECIALIZE mapG :: (a -> b) -> CoercionMapG a -> CoercionMapG b #-}
{-# SPECIALIZE mapG :: (a -> b) -> CoreMapG a     -> CoreMapG b #-}

{-# SPECIALIZE fdG :: (a -> b -> b) -> TypeMapG a     -> b -> b #-}
{-# SPECIALIZE fdG :: (a -> b -> b) -> CoercionMapG a -> b -> b #-}
{-# SPECIALIZE fdG :: (a -> b -> b) -> CoreMapG a     -> b -> b #-}


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

lkDNamed :: NamedThing n => n -> DNameEnv a -> Maybe a
lkDNamed :: n -> DNameEnv a -> Maybe a
lkDNamed n :: n
n env :: DNameEnv a
env = DNameEnv a -> Name -> Maybe a
forall a. DNameEnv a -> Name -> Maybe a
lookupDNameEnv DNameEnv a
env (n -> Name
forall a. NamedThing a => a -> Name
getName n
n)

xtDNamed :: NamedThing n => n -> XT a -> DNameEnv a -> DNameEnv a
xtDNamed :: n -> XT a -> DNameEnv a -> DNameEnv a
xtDNamed tc :: n
tc f :: XT a
f m :: DNameEnv a
m = XT a -> DNameEnv a -> Name -> DNameEnv a
forall a. (Maybe a -> Maybe a) -> DNameEnv a -> Name -> DNameEnv a
alterDNameEnv XT a
f DNameEnv a
m (n -> Name
forall a. NamedThing a => a -> Name
getName n
tc)


{-
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 (Trac #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 CoreSyn.
-}

-- | @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)

instance TrieMap CoreMap where
    type Key CoreMap = CoreExpr
    emptyTM :: CoreMap a
emptyTM = CoreMapG a -> CoreMap a
forall a. CoreMapG a -> CoreMap a
CoreMap CoreMapG a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
    lookupTM :: Key CoreMap -> CoreMap b -> Maybe b
lookupTM k :: Key CoreMap
k (CoreMap m :: CoreMapG b
m) = Key (GenMap CoreMapX) -> CoreMapG b -> Maybe b
forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM (CoreExpr -> DeBruijn CoreExpr
forall a. a -> DeBruijn a
deBruijnize Key CoreMap
CoreExpr
k) CoreMapG b
m
    alterTM :: Key CoreMap -> XT b -> CoreMap b -> CoreMap b
alterTM k :: Key CoreMap
k f :: XT b
f (CoreMap m :: CoreMapG b
m) = CoreMapG b -> CoreMap b
forall a. CoreMapG a -> CoreMap a
CoreMap (Key (GenMap CoreMapX) -> XT b -> CoreMapG b -> CoreMapG b
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM (CoreExpr -> DeBruijn CoreExpr
forall a. a -> DeBruijn a
deBruijnize Key CoreMap
CoreExpr
k) XT b
f CoreMapG b
m)
    foldTM :: (a -> b -> b) -> CoreMap a -> b -> b
foldTM k :: a -> b -> b
k (CoreMap m :: CoreMapG a
m) = (a -> b -> b) -> CoreMapG a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k CoreMapG a
m
    mapTM :: (a -> b) -> CoreMap a -> CoreMap b
mapTM f :: a -> b
f (CoreMap m :: CoreMapG a
m) = CoreMapG b -> CoreMap b
forall a. CoreMapG a -> CoreMap a
CoreMap ((a -> b) -> CoreMapG a -> CoreMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
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

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

instance Eq (DeBruijn CoreExpr) where
  D env1 :: CmEnv
env1 e1 :: CoreExpr
e1 == :: DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool
== D env2 :: CmEnv
env2 e2 :: CoreExpr
e2 = CoreExpr -> CoreExpr -> Bool
go CoreExpr
e1 CoreExpr
e2 where
    go :: CoreExpr -> CoreExpr -> Bool
go (Var v1 :: Id
v1) (Var v2 :: Id
v2) = case (CmEnv -> Id -> Maybe BoundVar
lookupCME CmEnv
env1 Id
v1, CmEnv -> Id -> Maybe BoundVar
lookupCME CmEnv
env2 Id
v2) of
                            (Just b1 :: BoundVar
b1, Just b2 :: BoundVar
b2) -> BoundVar
b1 BoundVar -> BoundVar -> Bool
forall a. Eq a => a -> a -> Bool
== BoundVar
b2
                            (Nothing, Nothing) -> Id
v1 Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
v2
                            _ -> Bool
False
    go (Lit lit1 :: Literal
lit1)    (Lit lit2 :: Literal
lit2)      = Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2
    go (Type t1 :: Type
t1)    (Type t2 :: Type
t2)        = CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 Type
t1 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2 Type
t2
    go (Coercion co1 :: Coercion
co1) (Coercion co2 :: Coercion
co2) = CmEnv -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 Coercion
co1 DeBruijn Coercion -> DeBruijn Coercion -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2 Coercion
co2
    go (Cast e1 :: CoreExpr
e1 co1 :: Coercion
co1) (Cast e2 :: CoreExpr
e2 co2 :: Coercion
co2) = CmEnv -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 Coercion
co1 DeBruijn Coercion -> DeBruijn Coercion -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2 Coercion
co2 Bool -> Bool -> Bool
&& CoreExpr -> CoreExpr -> Bool
go CoreExpr
e1 CoreExpr
e2
    go (App f1 :: CoreExpr
f1 a1 :: CoreExpr
a1)   (App f2 :: CoreExpr
f2 a2 :: CoreExpr
a2)   = CoreExpr -> CoreExpr -> Bool
go CoreExpr
f1 CoreExpr
f2 Bool -> Bool -> Bool
&& CoreExpr -> CoreExpr -> Bool
go CoreExpr
a1 CoreExpr
a2
    -- This seems a bit dodgy, see 'eqTickish'
    go (Tick n1 :: Tickish Id
n1 e1 :: CoreExpr
e1)  (Tick n2 :: Tickish Id
n2 e2 :: CoreExpr
e2)  = Tickish Id
n1 Tickish Id -> Tickish Id -> Bool
forall a. Eq a => a -> a -> Bool
== Tickish Id
n2 Bool -> Bool -> Bool
&& CoreExpr -> CoreExpr -> Bool
go CoreExpr
e1 CoreExpr
e2

    go (Lam b1 :: Id
b1 e1 :: CoreExpr
e1)  (Lam b2 :: Id
b2 e2 :: CoreExpr
e2)
      =  CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 (Id -> Type
varType Id
b1) DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2 (Id -> Type
varType Id
b2)
      Bool -> Bool -> Bool
&& CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env1 Id
b1) CoreExpr
e1 DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env2 Id
b2) CoreExpr
e2

    go (Let (NonRec v1 :: Id
v1 r1 :: CoreExpr
r1) e1 :: CoreExpr
e1) (Let (NonRec v2 :: Id
v2 r2 :: CoreExpr
r2) e2 :: CoreExpr
e2)
      =  CoreExpr -> CoreExpr -> Bool
go CoreExpr
r1 CoreExpr
r2
      Bool -> Bool -> Bool
&& CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env1 Id
v1) CoreExpr
e1 DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env2 Id
v2) CoreExpr
e2

    go (Let (Rec ps1 :: [(Id, CoreExpr)]
ps1) e1 :: CoreExpr
e1) (Let (Rec ps2 :: [(Id, CoreExpr)]
ps2) e2 :: CoreExpr
e2)
      = [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [(Id, CoreExpr)]
ps1 [(Id, CoreExpr)]
ps2
      Bool -> Bool -> Bool
&& CmEnv -> [CoreExpr] -> DeBruijn [CoreExpr]
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1' [CoreExpr]
rs1 DeBruijn [CoreExpr] -> DeBruijn [CoreExpr] -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> [CoreExpr] -> DeBruijn [CoreExpr]
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2' [CoreExpr]
rs2
      Bool -> Bool -> Bool
&& CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1' CoreExpr
e1  DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2' CoreExpr
e2
      where
        (bs1 :: [Id]
bs1,rs1 :: [CoreExpr]
rs1) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
ps1
        (bs2 :: [Id]
bs2,rs2 :: [CoreExpr]
rs2) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
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 e1 :: CoreExpr
e1 b1 :: Id
b1 t1 :: Type
t1 a1 :: [Alt Id]
a1) (Case e2 :: CoreExpr
e2 b2 :: Id
b2 t2 :: Type
t2 a2 :: [Alt Id]
a2)
      | [Alt Id] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Id]
a1   -- See Note [Empty case alternatives]
      = [Alt Id] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Id]
a2 Bool -> Bool -> Bool
&& CoreExpr -> CoreExpr -> Bool
go CoreExpr
e1 CoreExpr
e2 Bool -> Bool -> Bool
&& CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 Type
t1 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2 Type
t2
      | Bool
otherwise
      =  CoreExpr -> CoreExpr -> Bool
go CoreExpr
e1 CoreExpr
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 _ _ = Bool
False

emptyE :: CoreMapX a
emptyE :: CoreMapX a
emptyE = CM :: forall a.
VarMap a
-> LiteralMap a
-> CoercionMapG a
-> TypeMapG a
-> CoreMapG (CoercionMapG a)
-> CoreMapG (TickishMap a)
-> CoreMapG (CoreMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (CoreMapG (TypeMapG a))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
-> CoreMapG (ListMap AltMap a)
-> CoreMapG (TypeMapG a)
-> CoreMapX a
CM { cm_var :: VarMap a
cm_var = VarMap a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM, cm_lit :: LiteralMap a
cm_lit = LiteralMap a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , cm_co :: CoercionMapG a
cm_co = CoercionMapG a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM, cm_type :: TypeMapG a
cm_type = TypeMapG a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , cm_cast :: CoreMapG (CoercionMapG a)
cm_cast = CoreMapG (CoercionMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM, cm_app :: CoreMapG (CoreMapG a)
cm_app = CoreMapG (CoreMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , cm_lam :: CoreMapG (TypeMapG a)
cm_lam = CoreMapG (TypeMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM, cm_letn :: CoreMapG (CoreMapG (TypeMapG a))
cm_letn = CoreMapG (CoreMapG (TypeMapG 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 (m :: * -> *) a. TrieMap m => m a
emptyTM, cm_case :: CoreMapG (ListMap AltMap a)
cm_case = CoreMapG (ListMap AltMap a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , cm_ecase :: CoreMapG (TypeMapG a)
cm_ecase = CoreMapG (TypeMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM, cm_tick :: CoreMapG (TickishMap a)
cm_tick = CoreMapG (TickishMap a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM }

instance TrieMap CoreMapX where
   type Key CoreMapX = DeBruijn CoreExpr
   emptyTM :: CoreMapX a
emptyTM  = CoreMapX a
forall a. CoreMapX a
emptyE
   lookupTM :: Key CoreMapX -> CoreMapX b -> Maybe b
lookupTM = Key CoreMapX -> CoreMapX b -> Maybe b
forall a. DeBruijn CoreExpr -> CoreMapX a -> Maybe a
lkE
   alterTM :: Key CoreMapX -> XT b -> CoreMapX b -> CoreMapX b
alterTM  = Key CoreMapX -> XT b -> CoreMapX b -> CoreMapX b
forall a. DeBruijn CoreExpr -> XT a -> CoreMapX a -> CoreMapX a
xtE
   foldTM :: (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
   mapTM :: (a -> b) -> CoreMapX a -> CoreMapX b
mapTM    = (a -> b) -> CoreMapX a -> CoreMapX b
forall a b. (a -> b) -> CoreMapX a -> CoreMapX b
mapE

--------------------------
mapE :: (a->b) -> CoreMapX a -> CoreMapX b
mapE :: (a -> b) -> CoreMapX a -> CoreMapX b
mapE f :: 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 (TypeMapG a)
cm_lam = CoreMapG (TypeMapG a)
clam, cm_letn :: forall a. CoreMapX a -> CoreMapG (CoreMapG (TypeMapG a))
cm_letn = CoreMapG (CoreMapG (TypeMapG 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 :: forall a.
VarMap a
-> LiteralMap a
-> CoercionMapG a
-> TypeMapG a
-> CoreMapG (CoercionMapG a)
-> CoreMapG (TickishMap a)
-> CoreMapG (CoreMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (CoreMapG (TypeMapG a))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
-> CoreMapG (ListMap AltMap a)
-> CoreMapG (TypeMapG a)
-> CoreMapX a
CM { cm_var :: VarMap b
cm_var = (a -> b) -> VarMap a -> VarMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f VarMap a
cvar, cm_lit :: LiteralMap b
cm_lit = (a -> b) -> LiteralMap a -> LiteralMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f LiteralMap a
clit
       , cm_co :: CoercionMapG b
cm_co = (a -> b) -> CoercionMapG a -> CoercionMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f CoercionMapG a
cco, cm_type :: TypeMapG b
cm_type = (a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f TypeMapG a
ctype
       , cm_cast :: CoreMapG (CoercionMapG b)
cm_cast = (CoercionMapG a -> CoercionMapG b)
-> CoreMapG (CoercionMapG a) -> CoreMapG (CoercionMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> CoercionMapG a -> CoercionMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM 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 (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> CoreMapG a -> CoreMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) CoreMapG (CoreMapG a)
capp
       , cm_lam :: CoreMapG (TypeMapG b)
cm_lam = (TypeMapG a -> TypeMapG b)
-> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) CoreMapG (TypeMapG a)
clam, cm_letn :: CoreMapG (CoreMapG (TypeMapG b))
cm_letn = (CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG b))
-> CoreMapG (CoreMapG (TypeMapG a))
-> CoreMapG (CoreMapG (TypeMapG b))
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((TypeMapG a -> TypeMapG b)
-> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f)) CoreMapG (CoreMapG (TypeMapG 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 (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((ListMap BndrMap a -> ListMap BndrMap b)
-> CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> ListMap BndrMap a -> ListMap BndrMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM 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 (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> ListMap AltMap a -> ListMap AltMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM 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 (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM 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 (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TickishMap a -> TickishMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) CoreMapG (TickishMap a)
ctick }

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

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

foldCoreMap :: (a -> b -> b) -> b -> CoreMap a -> b
foldCoreMap :: (a -> b -> b) -> b -> CoreMap a -> b
foldCoreMap k :: a -> b -> b
k z :: b
z m :: CoreMap a
m = (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 :: CoreMap a
emptyCoreMap = CoreMap a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM

instance Outputable a => Outputable (CoreMap a) where
  ppr :: CoreMap a -> SDoc
ppr m :: CoreMap a
m = String -> SDoc
text "CoreMap elts" SDoc -> SDoc -> SDoc
<+> [a] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((a -> [a] -> [a]) -> CoreMap a -> [a] -> [a]
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 :: (a -> b -> b) -> CoreMapX a -> b -> b
fdE k :: a -> b -> b
k m :: CoreMapX a
m
  = (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 (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 (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 (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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((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 (Tickish Id) a -> b -> b)
-> GenMap CoreMapX (Map (Tickish Id) a) -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((a -> b -> b) -> Map (Tickish Id) 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 (Tickish Id) 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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((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
. (GenMap TypeMapX a -> b -> b)
-> GenMap CoreMapX (GenMap TypeMapX 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 (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_lam CoreMapX a
m)
  (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenMap CoreMapX (GenMap TypeMapX a) -> b -> b)
-> GenMap CoreMapX (GenMap CoreMapX (GenMap TypeMapX a)) -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((GenMap TypeMapX a -> b -> b)
-> GenMap CoreMapX (GenMap TypeMapX 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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k)) (CoreMapX a -> GenMap CoreMapX (GenMap CoreMapX (GenMap TypeMapX a))
forall a. CoreMapX a -> CoreMapG (CoreMapG (TypeMapG 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 (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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((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 :: DeBruijn CoreExpr -> CoreMapX a -> Maybe a
lkE (D env :: CmEnv
env expr :: CoreExpr
expr) cm :: CoreMapX a
cm = CoreExpr -> CoreMapX a -> Maybe a
go CoreExpr
expr CoreMapX a
cm
  where
    go :: CoreExpr -> CoreMapX a -> Maybe a
go (Var v :: 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 l :: 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 (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM Literal
Key (Map Literal)
l
    go (Type t :: Type
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 -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t)
    go (Coercion c :: Coercion
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 -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Coercion
c)
    go (Cast e :: CoreExpr
e c :: Coercion
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
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 -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Coercion
c)
    go (Tick tickish :: Tickish Id
tickish e :: CoreExpr
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
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
>=> Tickish Id -> TickishMap a -> Maybe a
forall a. Tickish Id -> TickishMap a -> Maybe a
lkTickish Tickish Id
tickish
    go (App e1 :: CoreExpr
e1 e2 :: CoreExpr
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e1)
    go (Lam v :: Id
v e :: CoreExpr
e)            = CoreMapX a -> CoreMapG (TypeMapG a)
forall a. CoreMapX a -> CoreMapG (TypeMapG a)
cm_lam  (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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
v) CoreExpr
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
>=> CmEnv -> Id -> TypeMapG a -> Maybe a
forall a. CmEnv -> Id -> BndrMap a -> Maybe a
lkBndr CmEnv
env Id
v
    go (Let (NonRec b :: Id
b r :: CoreExpr
r) e :: CoreExpr
e) = CoreMapX a -> CoreMapG (CoreMapG (TypeMapG a))
forall a. CoreMapX a -> CoreMapG (CoreMapG (TypeMapG a))
cm_letn (CoreMapX a -> CoreMapG (CoreMapG (TypeMapG a)))
-> (CoreMapG (CoreMapG (TypeMapG a)) -> Maybe a)
-> CoreMapX a
-> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> Key CoreMapX
-> CoreMapG (CoreMapG (TypeMapG a))
-> Maybe (CoreMapG (TypeMapG a))
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
r)
                              (CoreMapG (CoreMapG (TypeMapG a)) -> Maybe (CoreMapG (TypeMapG a)))
-> (CoreMapG (TypeMapG a) -> Maybe a)
-> CoreMapG (CoreMapG (TypeMapG a))
-> Maybe a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m 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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
b) CoreExpr
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
>=> CmEnv -> Id -> TypeMapG a -> Maybe a
forall a. CmEnv -> Id -> BndrMap a -> Maybe a
lkBndr CmEnv
env Id
b
    go (Let (Rec prs :: [(Id, CoreExpr)]
prs) e :: CoreExpr
e)    = let (bndrs :: [Id]
bndrs,rhss :: [CoreExpr]
rhss) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
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. CoreExpr -> CoreMapG b -> Maybe b)
-> [CoreExpr]
-> 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 (DeBruijn CoreExpr -> GenMap CoreMapX b -> Maybe b
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (DeBruijn CoreExpr -> GenMap CoreMapX b -> Maybe b)
-> (CoreExpr -> DeBruijn CoreExpr)
-> CoreExpr
-> GenMap CoreMapX b
-> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1) [CoreExpr]
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 CoreExpr
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 e :: CoreExpr
e b :: Id
b ty :: Type
ty as :: [Alt Id]
as)     -- See Note [Empty case alternatives]
               | [Alt Id] -> 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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
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 -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
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 :: DeBruijn CoreExpr -> XT a -> CoreMapX a -> CoreMapX a
xtE (D env :: CmEnv
env (Var v :: Id
v))              f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_var :: VarMap a
cm_var  = CoreMapX a -> VarMap a
forall a. CoreMapX a -> VarMap a
cm_var CoreMapX a
m
                                                 VarMap a -> (VarMap a -> VarMap a) -> VarMap a
forall a b. a -> (a -> b) -> b
|> CmEnv -> Id -> XT a -> VarMap a -> VarMap a
forall a. CmEnv -> Id -> XT a -> VarMap a -> VarMap a
xtVar CmEnv
env Id
v XT a
f }
xtE (D env :: CmEnv
env (Type t :: Type
t))             f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_type :: TypeMapG a
cm_type = CoreMapX a -> TypeMapG a
forall a. CoreMapX a -> TypeMapG a
cm_type CoreMapX a
m
                                                 TypeMapG a -> (TypeMapG a -> TypeMapG a) -> TypeMapG a
forall a b. a -> (a -> b) -> b
|> Key TypeMapX -> XT a -> TypeMapG a -> TypeMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t) XT a
f }
xtE (D env :: CmEnv
env (Coercion c :: Coercion
c))         f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_co :: CoercionMapG a
cm_co   = CoreMapX a -> CoercionMapG a
forall a. CoreMapX a -> CoercionMapG a
cm_co CoreMapX a
m
                                                 CoercionMapG a
-> (CoercionMapG a -> CoercionMapG a) -> CoercionMapG a
forall a b. a -> (a -> b) -> b
|> Key CoercionMapX -> XT a -> CoercionMapG a -> CoercionMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Coercion
c) XT a
f }
xtE (D _   (Lit l :: Literal
l))              f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_lit :: LiteralMap a
cm_lit  = CoreMapX a -> LiteralMap a
forall a. CoreMapX a -> LiteralMap a
cm_lit CoreMapX a
m  LiteralMap a -> (LiteralMap a -> LiteralMap a) -> LiteralMap a
forall a b. a -> (a -> b) -> b
|> Key (Map Literal) -> XT a -> LiteralMap a -> LiteralMap a
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM Literal
Key (Map Literal)
l XT a
f }
xtE (D env :: CmEnv
env (Cast e :: CoreExpr
e c :: Coercion
c))           f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_cast :: CoreMapG (CoercionMapG a)
cm_cast = CoreMapX a -> CoreMapG (CoercionMapG a)
forall a. CoreMapX a -> CoreMapG (CoercionMapG a)
cm_cast CoreMapX a
m CoreMapG (CoercionMapG a)
-> (CoreMapG (CoercionMapG a) -> CoreMapG (CoercionMapG a))
-> CoreMapG (CoercionMapG a)
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (CoercionMapG a)
-> CoreMapG (CoercionMapG a)
-> CoreMapG (CoercionMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e)
                                                 (XT (CoercionMapG a)
 -> CoreMapG (CoercionMapG a) -> CoreMapG (CoercionMapG a))
-> (CoercionMapG a -> CoercionMapG a)
-> CoreMapG (CoercionMapG a)
-> CoreMapG (CoercionMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key CoercionMapX -> XT a -> CoercionMapG a -> CoercionMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Coercion -> DeBruijn Coercion
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Coercion
c) XT a
f }
xtE (D env :: CmEnv
env (Tick t :: Tickish Id
t e :: CoreExpr
e))           f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_tick :: CoreMapG (TickishMap a)
cm_tick = CoreMapX a -> CoreMapG (TickishMap a)
forall a. CoreMapX a -> CoreMapG (TickishMap a)
cm_tick CoreMapX a
m CoreMapG (TickishMap a)
-> (CoreMapG (TickishMap a) -> CoreMapG (TickishMap a))
-> CoreMapG (TickishMap a)
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (TickishMap a)
-> CoreMapG (TickishMap a)
-> CoreMapG (TickishMap a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e)
                                                 (XT (TickishMap a)
 -> CoreMapG (TickishMap a) -> CoreMapG (TickishMap a))
-> (TickishMap a -> TickishMap a)
-> CoreMapG (TickishMap a)
-> CoreMapG (TickishMap a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Tickish Id -> XT a -> TickishMap a -> TickishMap a
forall a. Tickish Id -> XT a -> TickishMap a -> TickishMap a
xtTickish Tickish Id
t XT a
f }
xtE (D env :: CmEnv
env (App e1 :: CoreExpr
e1 e2 :: CoreExpr
e2))          f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_app :: CoreMapG (CoreMapG a)
cm_app = CoreMapX a -> CoreMapG (CoreMapG a)
forall a. CoreMapX a -> CoreMapG (CoreMapG a)
cm_app CoreMapX a
m CoreMapG (CoreMapG a)
-> (CoreMapG (CoreMapG a) -> CoreMapG (CoreMapG a))
-> CoreMapG (CoreMapG a)
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (CoreMapG a)
-> CoreMapG (CoreMapG a)
-> CoreMapG (CoreMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e2)
                                                 (XT (CoreMapG a) -> CoreMapG (CoreMapG a) -> CoreMapG (CoreMapG a))
-> (CoreMapG a -> CoreMapG a)
-> CoreMapG (CoreMapG a)
-> CoreMapG (CoreMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key CoreMapX -> XT a -> CoreMapG a -> CoreMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e1) XT a
f }
xtE (D env :: CmEnv
env (Lam v :: Id
v e :: CoreExpr
e))            f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_lam :: CoreMapG (TypeMapG a)
cm_lam = CoreMapX a -> CoreMapG (TypeMapG a)
forall a. CoreMapX a -> CoreMapG (TypeMapG a)
cm_lam CoreMapX a
m
                                                 CoreMapG (TypeMapG a)
-> (CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a))
-> CoreMapG (TypeMapG a)
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (TypeMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
v) CoreExpr
e)
                                                 (XT (TypeMapG a) -> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a))
-> (TypeMapG a -> TypeMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (TypeMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> CmEnv -> Id -> XT a -> TypeMapG a -> TypeMapG a
forall a. CmEnv -> Id -> XT a -> BndrMap a -> BndrMap a
xtBndr CmEnv
env Id
v XT a
f }
xtE (D env :: CmEnv
env (Let (NonRec b :: Id
b r :: CoreExpr
r) e :: CoreExpr
e)) f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_letn :: CoreMapG (CoreMapG (TypeMapG a))
cm_letn = CoreMapX a -> CoreMapG (CoreMapG (TypeMapG a))
forall a. CoreMapX a -> CoreMapG (CoreMapG (TypeMapG a))
cm_letn CoreMapX a
m
                                                 CoreMapG (CoreMapG (TypeMapG a))
-> (CoreMapG (CoreMapG (TypeMapG a))
    -> CoreMapG (CoreMapG (TypeMapG a)))
-> CoreMapG (CoreMapG (TypeMapG a))
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (CoreMapG (TypeMapG a))
-> CoreMapG (CoreMapG (TypeMapG a))
-> CoreMapG (CoreMapG (TypeMapG a))
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
b) CoreExpr
e)
                                                 (XT (CoreMapG (TypeMapG a))
 -> CoreMapG (CoreMapG (TypeMapG a))
 -> CoreMapG (CoreMapG (TypeMapG a)))
-> (CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a))
-> CoreMapG (CoreMapG (TypeMapG a))
-> CoreMapG (CoreMapG (TypeMapG a))
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key CoreMapX
-> XT (TypeMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
r)
                                                 (XT (TypeMapG a) -> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a))
-> (TypeMapG a -> TypeMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (TypeMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> CmEnv -> Id -> XT a -> TypeMapG a -> TypeMapG a
forall a. CmEnv -> Id -> XT a -> BndrMap a -> BndrMap a
xtBndr CmEnv
env Id
b XT a
f }
xtE (D env :: CmEnv
env (Let (Rec prs :: [(Id, CoreExpr)]
prs) e :: CoreExpr
e))    f :: XT a
f m :: CoreMapX a
m = CoreMapX a
m { cm_letr :: ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
cm_letr =
                                              let (bndrs :: [Id]
bndrs,rhss :: [CoreExpr]
rhss) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
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
m
                                                 ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
-> (ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
    -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a)))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
forall a b. a -> (a -> b) -> b
|>  (forall b. CoreExpr -> XT b -> CoreMapG b -> CoreMapG b)
-> [CoreExpr]
-> XT (CoreMapG (ListMap BndrMap a))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
forall (m :: * -> *) k a.
TrieMap m =>
(forall b. k -> XT b -> m b -> m b)
-> [k] -> XT a -> ListMap m a -> ListMap m a
xtList (DeBruijn CoreExpr -> XT b -> GenMap CoreMapX b -> GenMap CoreMapX b
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (DeBruijn CoreExpr
 -> XT b -> GenMap CoreMapX b -> GenMap CoreMapX b)
-> (CoreExpr -> DeBruijn CoreExpr)
-> CoreExpr
-> XT b
-> GenMap CoreMapX b
-> GenMap CoreMapX b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1) [CoreExpr]
rhss
                                                 (XT (CoreMapG (ListMap BndrMap a))
 -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
 -> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a)))
-> (CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap a))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
-> ListMap (GenMap CoreMapX) (CoreMapG (ListMap BndrMap a))
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key CoreMapX
-> XT (ListMap BndrMap a)
-> CoreMapG (ListMap BndrMap a)
-> CoreMapG (ListMap BndrMap a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 CoreExpr
e)
                                                 (XT (ListMap BndrMap a)
 -> CoreMapG (ListMap BndrMap a) -> CoreMapG (ListMap BndrMap a))
-> (ListMap BndrMap a -> ListMap BndrMap a)
-> CoreMapG (ListMap BndrMap a)
-> CoreMapG (ListMap BndrMap a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> (forall b. Id -> XT b -> BndrMap b -> BndrMap b)
-> [Id] -> XT a -> ListMap BndrMap a -> ListMap BndrMap a
forall (m :: * -> *) k a.
TrieMap m =>
(forall b. k -> XT b -> m b -> m b)
-> [k] -> XT a -> ListMap m a -> ListMap m a
xtList (CmEnv -> Id -> XT b -> BndrMap b -> BndrMap b
forall a. CmEnv -> Id -> XT a -> BndrMap a -> BndrMap a
xtBndr CmEnv
env1)
                                                            [Id]
bndrs XT a
f }
xtE (D env :: CmEnv
env (Case e :: CoreExpr
e b :: Id
b ty :: Type
ty as :: [Alt Id]
as))     f :: XT a
f m :: CoreMapX a
m
                     | [Alt Id] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Id]
as   = CoreMapX a
m { cm_ecase :: CoreMapG (TypeMapG a)
cm_ecase = CoreMapX a -> CoreMapG (TypeMapG a)
forall a. CoreMapX a -> CoreMapG (TypeMapG a)
cm_ecase CoreMapX a
m CoreMapG (TypeMapG a)
-> (CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a))
-> CoreMapG (TypeMapG a)
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (TypeMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e)
                                                 (XT (TypeMapG a) -> CoreMapG (TypeMapG a) -> CoreMapG (TypeMapG a))
-> (TypeMapG a -> TypeMapG a)
-> CoreMapG (TypeMapG a)
-> CoreMapG (TypeMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key TypeMapX -> XT a -> TypeMapG a -> TypeMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
ty) XT a
f }
                     | Bool
otherwise = CoreMapX a
m { cm_case :: CoreMapG (ListMap AltMap a)
cm_case = CoreMapX a -> CoreMapG (ListMap AltMap a)
forall a. CoreMapX a -> CoreMapG (ListMap AltMap a)
cm_case CoreMapX a
m CoreMapG (ListMap AltMap a)
-> (CoreMapG (ListMap AltMap a) -> CoreMapG (ListMap AltMap a))
-> CoreMapG (ListMap AltMap a)
forall a b. a -> (a -> b) -> b
|> Key CoreMapX
-> XT (ListMap AltMap a)
-> CoreMapG (ListMap AltMap a)
-> CoreMapG (ListMap AltMap a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
e)
                                                 (XT (ListMap AltMap a)
 -> CoreMapG (ListMap AltMap a) -> CoreMapG (ListMap AltMap a))
-> (ListMap AltMap a -> ListMap AltMap a)
-> CoreMapG (ListMap AltMap a)
-> CoreMapG (ListMap AltMap a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> let env1 :: CmEnv
env1 = CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
b
                                                     in (forall b. Alt Id -> XT b -> AltMap b -> AltMap b)
-> [Alt Id] -> XT a -> ListMap AltMap a -> ListMap AltMap a
forall (m :: * -> *) k a.
TrieMap m =>
(forall b. k -> XT b -> m b -> m b)
-> [k] -> XT a -> ListMap m a -> ListMap m a
xtList (CmEnv -> Alt Id -> XT b -> AltMap b -> AltMap b
forall a. CmEnv -> Alt Id -> XT a -> AltMap a -> AltMap a
xtA CmEnv
env1) [Alt Id]
as XT a
f }

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

xtTickish :: Tickish Id -> XT a -> TickishMap a -> TickishMap a
xtTickish :: Tickish Id -> XT a -> TickishMap a -> TickishMap a
xtTickish = Tickish Id -> XT a -> TickishMap a -> TickishMap a
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM

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

instance TrieMap AltMap where
   type Key AltMap = CoreAlt
   emptyTM :: AltMap a
emptyTM  = AM :: forall a.
CoreMapG a
-> DNameEnv (CoreMapG a) -> LiteralMap (CoreMapG a) -> AltMap a
AM { am_deflt :: CoreMapG a
am_deflt = CoreMapG 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 (m :: * -> *) a. TrieMap m => m a
emptyTM }
   lookupTM :: 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 :: Key AltMap -> XT b -> AltMap b -> AltMap b
alterTM  = CmEnv -> Alt Id -> XT b -> AltMap b -> AltMap b
forall a. CmEnv -> Alt Id -> XT a -> AltMap a -> AltMap a
xtA CmEnv
emptyCME
   foldTM :: (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
   mapTM :: (a -> b) -> AltMap a -> AltMap b
mapTM    = (a -> b) -> AltMap a -> AltMap b
forall a b. (a -> b) -> AltMap a -> AltMap b
mapA

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

mapA :: (a->b) -> AltMap a -> AltMap b
mapA :: (a -> b) -> AltMap a -> AltMap b
mapA f :: 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 :: forall a.
CoreMapG a
-> DNameEnv (CoreMapG a) -> LiteralMap (CoreMapG a) -> AltMap a
AM { am_deflt :: CoreMapG b
am_deflt = (a -> b) -> CoreMapG a -> CoreMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f CoreMapG a
adeflt
       , am_data :: DNameEnv (CoreMapG b)
am_data = (CoreMapG a -> CoreMapG b)
-> DNameEnv (CoreMapG a) -> DNameEnv (CoreMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> CoreMapG a -> CoreMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM 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 (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> CoreMapG a -> CoreMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) LiteralMap (CoreMapG a)
alit }

lkA :: CmEnv -> CoreAlt -> AltMap a -> Maybe a
lkA :: CmEnv -> Alt Id -> AltMap a -> Maybe a
lkA env :: CmEnv
env (DEFAULT,    _, rhs :: CoreExpr
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
rhs)
lkA env :: CmEnv
env (LitAlt lit :: Literal
lit, _, rhs :: CoreExpr
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 (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM Literal
Key (Map 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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
rhs)
lkA env :: CmEnv
env (DataAlt dc :: DataCon
dc, bs :: [Id]
bs, rhs :: CoreExpr
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 -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> [Id] -> CmEnv
extendCMEs CmEnv
env [Id]
bs) CoreExpr
rhs)

xtA :: CmEnv -> CoreAlt -> XT a -> AltMap a -> AltMap a
xtA :: CmEnv -> Alt Id -> XT a -> AltMap a -> AltMap a
xtA env :: CmEnv
env (DEFAULT, _, rhs :: CoreExpr
rhs)    f :: XT a
f m :: AltMap a
m =
    AltMap a
m { am_deflt :: CoreMapG a
am_deflt = AltMap a -> CoreMapG a
forall a. AltMap a -> CoreMapG a
am_deflt AltMap a
m CoreMapG a -> (CoreMapG a -> CoreMapG a) -> CoreMapG a
forall a b. a -> (a -> b) -> b
|> Key CoreMapX -> XT a -> CoreMapG a -> CoreMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
rhs) XT a
f }
xtA env :: CmEnv
env (LitAlt l :: Literal
l, _, rhs :: CoreExpr
rhs)   f :: XT a
f m :: AltMap a
m =
    AltMap a
m { am_lit :: LiteralMap (CoreMapG a)
am_lit   = AltMap a -> LiteralMap (CoreMapG a)
forall a. AltMap a -> LiteralMap (CoreMapG a)
am_lit AltMap a
m   LiteralMap (CoreMapG a)
-> (LiteralMap (CoreMapG a) -> LiteralMap (CoreMapG a))
-> LiteralMap (CoreMapG a)
forall a b. a -> (a -> b) -> b
|> Key (Map Literal)
-> XT (CoreMapG a)
-> LiteralMap (CoreMapG a)
-> LiteralMap (CoreMapG a)
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM Literal
Key (Map Literal)
l (XT (CoreMapG a)
 -> LiteralMap (CoreMapG a) -> LiteralMap (CoreMapG a))
-> (CoreMapG a -> CoreMapG a)
-> LiteralMap (CoreMapG a)
-> LiteralMap (CoreMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key CoreMapX -> XT a -> CoreMapG a -> CoreMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env CoreExpr
rhs) XT a
f }
xtA env :: CmEnv
env (DataAlt d :: DataCon
d, bs :: [Id]
bs, rhs :: CoreExpr
rhs) f :: XT a
f m :: AltMap a
m =
    AltMap a
m { am_data :: DNameEnv (CoreMapG a)
am_data  = AltMap a -> DNameEnv (CoreMapG a)
forall a. AltMap a -> DNameEnv (CoreMapG a)
am_data AltMap a
m  DNameEnv (CoreMapG a)
-> (DNameEnv (CoreMapG a) -> DNameEnv (CoreMapG a))
-> DNameEnv (CoreMapG a)
forall a b. a -> (a -> b) -> b
|> DataCon
-> XT (CoreMapG a)
-> DNameEnv (CoreMapG a)
-> DNameEnv (CoreMapG a)
forall n a. NamedThing n => n -> XT a -> DNameEnv a -> DNameEnv a
xtDNamed DataCon
d
                             (XT (CoreMapG a) -> DNameEnv (CoreMapG a) -> DNameEnv (CoreMapG a))
-> (CoreMapG a -> CoreMapG a)
-> DNameEnv (CoreMapG a)
-> DNameEnv (CoreMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key CoreMapX -> XT a -> CoreMapG a -> CoreMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> CoreExpr -> DeBruijn CoreExpr
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> [Id] -> CmEnv
extendCMEs CmEnv
env [Id]
bs) CoreExpr
rhs) XT a
f }

fdA :: (a -> b -> b) -> AltMap a -> b -> b
fdA :: (a -> b -> b) -> AltMap a -> b -> b
fdA k :: a -> b -> b
k m :: AltMap a
m = (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 (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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k) (AltMap a -> UniqDFM (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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((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)

{-
************************************************************************
*                                                                      *
                   Coercions
*                                                                      *
************************************************************************
-}

-- We should really never care about the contents of a coercion. Instead,
-- just look up the coercion's type.
newtype CoercionMap a = CoercionMap (CoercionMapG a)

instance TrieMap CoercionMap where
   type Key CoercionMap = Coercion
   emptyTM :: CoercionMap a
emptyTM                     = CoercionMapG a -> CoercionMap a
forall a. CoercionMapG a -> CoercionMap a
CoercionMap CoercionMapG a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
   lookupTM :: Key CoercionMap -> CoercionMap b -> Maybe b
lookupTM k :: Key CoercionMap
k  (CoercionMap m :: CoercionMapG b
m) = Key (GenMap CoercionMapX) -> CoercionMapG b -> Maybe b
forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM (Coercion -> DeBruijn Coercion
forall a. a -> DeBruijn a
deBruijnize Coercion
Key CoercionMap
k) CoercionMapG b
m
   alterTM :: Key CoercionMap -> XT b -> CoercionMap b -> CoercionMap b
alterTM k :: Key CoercionMap
k f :: XT b
f (CoercionMap m :: CoercionMapG b
m) = CoercionMapG b -> CoercionMap b
forall a. CoercionMapG a -> CoercionMap a
CoercionMap (Key (GenMap CoercionMapX)
-> XT b -> CoercionMapG b -> CoercionMapG b
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM (Coercion -> DeBruijn Coercion
forall a. a -> DeBruijn a
deBruijnize Coercion
Key CoercionMap
k) XT b
f CoercionMapG b
m)
   foldTM :: (a -> b -> b) -> CoercionMap a -> b -> b
foldTM k :: a -> b -> b
k    (CoercionMap m :: CoercionMapG a
m) = (a -> b -> b) -> CoercionMapG a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k CoercionMapG a
m
   mapTM :: (a -> b) -> CoercionMap a -> CoercionMap b
mapTM f :: a -> b
f     (CoercionMap m :: CoercionMapG a
m) = CoercionMapG b -> CoercionMap b
forall a. CoercionMapG a -> CoercionMap a
CoercionMap ((a -> b) -> CoercionMapG a -> CoercionMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f CoercionMapG a
m)

type CoercionMapG = GenMap CoercionMapX
newtype CoercionMapX a = CoercionMapX (TypeMapX a)

instance TrieMap CoercionMapX where
  type Key CoercionMapX = DeBruijn Coercion
  emptyTM :: CoercionMapX a
emptyTM = TypeMapX a -> CoercionMapX a
forall a. TypeMapX a -> CoercionMapX a
CoercionMapX TypeMapX a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
  lookupTM :: Key CoercionMapX -> CoercionMapX b -> Maybe b
lookupTM = Key CoercionMapX -> CoercionMapX b -> Maybe b
forall a. DeBruijn Coercion -> CoercionMapX a -> Maybe a
lkC
  alterTM :: Key CoercionMapX -> XT b -> CoercionMapX b -> CoercionMapX b
alterTM  = Key CoercionMapX -> XT b -> CoercionMapX b -> CoercionMapX b
forall a.
DeBruijn Coercion -> XT a -> CoercionMapX a -> CoercionMapX a
xtC
  foldTM :: (a -> b -> b) -> CoercionMapX a -> b -> b
foldTM f :: a -> b -> b
f (CoercionMapX core_tm :: TypeMapX a
core_tm) = (a -> b -> b) -> TypeMapX a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
f TypeMapX a
core_tm
  mapTM :: (a -> b) -> CoercionMapX a -> CoercionMapX b
mapTM f :: a -> b
f (CoercionMapX core_tm :: TypeMapX a
core_tm)  = TypeMapX b -> CoercionMapX b
forall a. TypeMapX a -> CoercionMapX a
CoercionMapX ((a -> b) -> TypeMapX a -> TypeMapX b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f TypeMapX a
core_tm)

instance Eq (DeBruijn Coercion) where
  D env1 :: CmEnv
env1 co1 :: Coercion
co1 == :: DeBruijn Coercion -> DeBruijn Coercion -> Bool
== D env2 :: CmEnv
env2 co2 :: Coercion
co2
    = CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env1 (Coercion -> Type
coercionType Coercion
co1) DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
==
      CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env2 (Coercion -> Type
coercionType Coercion
co2)

lkC :: DeBruijn Coercion -> CoercionMapX a -> Maybe a
lkC :: DeBruijn Coercion -> CoercionMapX a -> Maybe a
lkC (D env :: CmEnv
env co :: Coercion
co) (CoercionMapX core_tm :: TypeMapX a
core_tm) = DeBruijn Type -> TypeMapX a -> Maybe a
forall a. DeBruijn Type -> TypeMapX a -> Maybe a
lkT (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Type -> DeBruijn Type) -> Type -> DeBruijn Type
forall a b. (a -> b) -> a -> b
$ Coercion -> Type
coercionType Coercion
co)
                                        TypeMapX a
core_tm

xtC :: DeBruijn Coercion -> XT a -> CoercionMapX a -> CoercionMapX a
xtC :: DeBruijn Coercion -> XT a -> CoercionMapX a -> CoercionMapX a
xtC (D env :: CmEnv
env co :: Coercion
co) f :: XT a
f (CoercionMapX m :: TypeMapX a
m)
  = TypeMapX a -> CoercionMapX a
forall a. TypeMapX a -> CoercionMapX a
CoercionMapX (DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
forall a. DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
xtT (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Type -> DeBruijn Type) -> Type -> DeBruijn Type
forall a b. (a -> b) -> a -> b
$ Coercion -> Type
coercionType Coercion
co) XT a
f TypeMapX a
m)

{-
************************************************************************
*                                                                      *
                   Types
*                                                                      *
************************************************************************
-}

-- | @TypeMapG a@ is a map from @DeBruijn Type@ 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 'TypeMap'
-- inside another 'TrieMap', this is the type you want. Note that this
-- lookup does not do a kind-check. Thus, all keys in this map must have
-- the same kind. Also note that this map respects the distinction between
-- @Type@ and @Constraint@, despite the fact that they are equivalent type
-- synonyms in Core.
type TypeMapG = GenMap TypeMapX

-- | @TypeMapX a@ is the base map from @DeBruijn Type@ to @a@, but without the
-- 'GenMap' optimization.
data TypeMapX a
  = TM { TypeMapX a -> VarMap a
tm_var    :: VarMap a
       , TypeMapX a -> TypeMapG (TypeMapG a)
tm_app    :: TypeMapG (TypeMapG a)
       , TypeMapX a -> DNameEnv a
tm_tycon  :: DNameEnv a
       , TypeMapX a -> TypeMapG (BndrMap a)
tm_forall :: TypeMapG (BndrMap a) -- See Note [Binders]
       , TypeMapX a -> TyLitMap a
tm_tylit  :: TyLitMap a
       , TypeMapX a -> Maybe a
tm_coerce :: Maybe a
       }
    -- Note that there is no tyconapp case; see Note [Equality on AppTys] in Type

-- | Squeeze out any synonyms, and change TyConApps to nested AppTys. Why the
-- last one? See Note [Equality on AppTys] in Type
--
-- Note, however, that we keep Constraint and Type apart here, despite the fact
-- that they are both synonyms of TYPE 'LiftedRep (see #11715).
trieMapView :: Type -> Maybe Type
trieMapView :: Type -> Maybe Type
trieMapView ty :: Type
ty
  -- First check for TyConApps that need to be expanded to
  -- AppTy chains.
  | Just (tc :: TyCon
tc, tys :: [Type]
tys@(_:_)) <- HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe Type
ty
  = Type -> Maybe Type
forall a. a -> Maybe a
Just (Type -> Maybe Type) -> Type -> Maybe Type
forall a b. (a -> b) -> a -> b
$ (Type -> Type -> Type) -> Type -> [Type] -> Type
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Type -> Type -> Type
AppTy (TyCon -> [Type] -> Type
TyConApp TyCon
tc []) [Type]
tys

  -- Then resolve any remaining nullary synonyms.
  | Just ty' :: Type
ty' <- Type -> Maybe Type
tcView Type
ty = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
ty'
trieMapView _ = Maybe Type
forall a. Maybe a
Nothing

instance TrieMap TypeMapX where
   type Key TypeMapX = DeBruijn Type
   emptyTM :: TypeMapX a
emptyTM  = TypeMapX a
forall a. TypeMapX a
emptyT
   lookupTM :: Key TypeMapX -> TypeMapX b -> Maybe b
lookupTM = Key TypeMapX -> TypeMapX b -> Maybe b
forall a. DeBruijn Type -> TypeMapX a -> Maybe a
lkT
   alterTM :: Key TypeMapX -> XT b -> TypeMapX b -> TypeMapX b
alterTM  = Key TypeMapX -> XT b -> TypeMapX b -> TypeMapX b
forall a. DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
xtT
   foldTM :: (a -> b -> b) -> TypeMapX a -> b -> b
foldTM   = (a -> b -> b) -> TypeMapX a -> b -> b
forall a b. (a -> b -> b) -> TypeMapX a -> b -> b
fdT
   mapTM :: (a -> b) -> TypeMapX a -> TypeMapX b
mapTM    = (a -> b) -> TypeMapX a -> TypeMapX b
forall a b. (a -> b) -> TypeMapX a -> TypeMapX b
mapT

instance Eq (DeBruijn Type) where
  env_t :: DeBruijn Type
env_t@(D env :: CmEnv
env t :: Type
t) == :: DeBruijn Type -> DeBruijn Type -> Bool
== env_t' :: DeBruijn Type
env_t'@(D env' :: CmEnv
env' t' :: Type
t')
    | Just new_t :: Type
new_t  <- Type -> Maybe Type
tcView Type
t  = CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
new_t DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== DeBruijn Type
env_t'
    | Just new_t' :: Type
new_t' <- Type -> Maybe Type
tcView Type
t' = DeBruijn Type
env_t       DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
new_t'
    | Bool
otherwise
    = case (Type
t, Type
t') of
        (CastTy t1 :: Type
t1 _, _)  -> CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t'
        (_, CastTy t1' :: Type
t1' _) -> CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t  DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1'

        (TyVarTy v :: Id
v, TyVarTy v' :: Id
v')
            -> case (CmEnv -> Id -> Maybe BoundVar
lookupCME CmEnv
env Id
v, CmEnv -> Id -> Maybe BoundVar
lookupCME CmEnv
env' Id
v') of
                (Just bv :: BoundVar
bv, Just bv' :: BoundVar
bv') -> BoundVar
bv BoundVar -> BoundVar -> Bool
forall a. Eq a => a -> a -> Bool
== BoundVar
bv'
                (Nothing, Nothing)  -> Id
v Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
v'
                _ -> Bool
False
                -- See Note [Equality on AppTys] in Type
        (AppTy t1 :: Type
t1 t2 :: Type
t2, s :: Type
s) | Just (t1' :: Type
t1', t2' :: Type
t2') <- HasDebugCallStack => Type -> Maybe (Type, Type)
Type -> Maybe (Type, Type)
repSplitAppTy_maybe Type
s
            -> CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
t1' Bool -> Bool -> Bool
&& CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t2 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
t2'
        (s :: Type
s, AppTy t1' :: Type
t1' t2' :: Type
t2') | Just (t1 :: Type
t1, t2 :: Type
t2) <- HasDebugCallStack => Type -> Maybe (Type, Type)
Type -> Maybe (Type, Type)
repSplitAppTy_maybe Type
s
            -> CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
t1' Bool -> Bool -> Bool
&& CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t2 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
t2'
        (FunTy t1 :: Type
t1 t2 :: Type
t2, FunTy t1' :: Type
t1' t2' :: Type
t2')
            -> CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
t1' Bool -> Bool -> Bool
&& CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t2 DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' Type
t2'
        (TyConApp tc :: TyCon
tc tys :: [Type]
tys, TyConApp tc' :: TyCon
tc' tys' :: [Type]
tys')
            -> TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc' Bool -> Bool -> Bool
&& CmEnv -> [Type] -> DeBruijn [Type]
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env [Type]
tys DeBruijn [Type] -> DeBruijn [Type] -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> [Type] -> DeBruijn [Type]
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' [Type]
tys'
        (LitTy l :: TyLit
l, LitTy l' :: TyLit
l')
            -> TyLit
l TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
l'
        (ForAllTy (Bndr tv :: Id
tv _) ty :: Type
ty, ForAllTy (Bndr tv' :: Id
tv' _) ty' :: Type
ty')
            -> CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Id -> Type
varType Id
tv)      DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' (Id -> Type
varType Id
tv') Bool -> Bool -> Bool
&&
               CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
tv) Type
ty DeBruijn Type -> DeBruijn Type -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env' Id
tv') Type
ty'
        (CoercionTy {}, CoercionTy {})
            -> Bool
True
        _ -> Bool
False

instance {-# OVERLAPPING #-}
         Outputable a => Outputable (TypeMapG a) where
  ppr :: TypeMapG a -> SDoc
ppr m :: TypeMapG a
m = String -> SDoc
text "TypeMap elts" SDoc -> SDoc -> SDoc
<+> [a] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((a -> [a] -> [a]) -> TypeMapG a -> [a] -> [a]
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM (:) TypeMapG a
m [])

emptyT :: TypeMapX a
emptyT :: TypeMapX a
emptyT = TM :: forall a.
VarMap a
-> TypeMapG (TypeMapG a)
-> DNameEnv a
-> TypeMapG (TypeMapG a)
-> TyLitMap a
-> Maybe a
-> TypeMapX a
TM { tm_var :: VarMap a
tm_var  = VarMap a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , tm_app :: TypeMapG (TypeMapG a)
tm_app  = TypeMapG (TypeMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , tm_tycon :: DNameEnv a
tm_tycon  = DNameEnv a
forall a. DNameEnv a
emptyDNameEnv
            , tm_forall :: TypeMapG (TypeMapG a)
tm_forall = TypeMapG (TypeMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
            , tm_tylit :: TyLitMap a
tm_tylit  = TyLitMap a
forall a. TyLitMap a
emptyTyLitMap
            , tm_coerce :: Maybe a
tm_coerce = Maybe a
forall a. Maybe a
Nothing }

mapT :: (a->b) -> TypeMapX a -> TypeMapX b
mapT :: (a -> b) -> TypeMapX a -> TypeMapX b
mapT f :: a -> b
f (TM { tm_var :: forall a. TypeMapX a -> VarMap a
tm_var  = VarMap a
tvar, tm_app :: forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_app = TypeMapG (TypeMapG a)
tapp, tm_tycon :: forall a. TypeMapX a -> DNameEnv a
tm_tycon = DNameEnv a
ttycon
           , tm_forall :: forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_forall = TypeMapG (TypeMapG a)
tforall, tm_tylit :: forall a. TypeMapX a -> TyLitMap a
tm_tylit = TyLitMap a
tlit
           , tm_coerce :: forall a. TypeMapX a -> Maybe a
tm_coerce = Maybe a
tcoerce })
  = TM :: forall a.
VarMap a
-> TypeMapG (TypeMapG a)
-> DNameEnv a
-> TypeMapG (TypeMapG a)
-> TyLitMap a
-> Maybe a
-> TypeMapX a
TM { tm_var :: VarMap b
tm_var    = (a -> b) -> VarMap a -> VarMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f VarMap a
tvar
       , tm_app :: TypeMapG (TypeMapG b)
tm_app    = (TypeMapG a -> TypeMapG b)
-> TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) TypeMapG (TypeMapG a)
tapp
       , tm_tycon :: DNameEnv b
tm_tycon  = (a -> b) -> DNameEnv a -> DNameEnv b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f DNameEnv a
ttycon
       , tm_forall :: TypeMapG (TypeMapG b)
tm_forall = (TypeMapG a -> TypeMapG b)
-> TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) TypeMapG (TypeMapG a)
tforall
       , tm_tylit :: TyLitMap b
tm_tylit  = (a -> b) -> TyLitMap a -> TyLitMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f TyLitMap a
tlit
       , tm_coerce :: Maybe b
tm_coerce = (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Maybe a
tcoerce }

-----------------
lkT :: DeBruijn Type -> TypeMapX a -> Maybe a
lkT :: DeBruijn Type -> TypeMapX a -> Maybe a
lkT (D env :: CmEnv
env ty :: Type
ty) m :: TypeMapX a
m = Type -> TypeMapX a -> Maybe a
go Type
ty TypeMapX a
m
  where
    go :: Type -> TypeMapX a -> Maybe a
go ty :: Type
ty | Just ty' :: Type
ty' <- Type -> Maybe Type
trieMapView Type
ty = Type -> TypeMapX a -> Maybe a
go Type
ty'
    go (TyVarTy v :: Id
v)                 = TypeMapX a -> VarMap a
forall a. TypeMapX a -> VarMap a
tm_var    (TypeMapX a -> VarMap a)
-> (VarMap a -> Maybe a) -> TypeMapX 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 (AppTy t1 :: Type
t1 t2 :: Type
t2)               = TypeMapX a -> TypeMapG (TypeMapG a)
forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_app    (TypeMapX a -> TypeMapG (TypeMapG a))
-> (TypeMapG (TypeMapG a) -> Maybe a) -> TypeMapX a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> Key TypeMapX -> TypeMapG (TypeMapG a) -> Maybe (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1)
                                               (TypeMapG (TypeMapG a) -> Maybe (TypeMapG a))
-> (TypeMapG a -> Maybe a) -> TypeMapG (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 -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t2)
    go (TyConApp tc :: TyCon
tc [])            = TypeMapX a -> DNameEnv a
forall a. TypeMapX a -> DNameEnv a
tm_tycon  (TypeMapX a -> DNameEnv a)
-> (DNameEnv a -> Maybe a) -> TypeMapX a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> TyCon -> DNameEnv a -> Maybe a
forall n a. NamedThing n => n -> DNameEnv a -> Maybe a
lkDNamed TyCon
tc
    go ty :: Type
ty@(TyConApp _ (_:_))       = String -> SDoc -> TypeMapX a -> Maybe a
forall a. HasCallStack => String -> SDoc -> a
pprPanic "lkT TyConApp" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
    go (LitTy l :: TyLit
l)                   = TypeMapX a -> TyLitMap a
forall a. TypeMapX a -> TyLitMap a
tm_tylit  (TypeMapX a -> TyLitMap a)
-> (TyLitMap a -> Maybe a) -> TypeMapX a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> TyLit -> TyLitMap a -> Maybe a
forall a. TyLit -> TyLitMap a -> Maybe a
lkTyLit TyLit
l
    go (ForAllTy (Bndr tv :: Id
tv _) ty :: Type
ty)   = TypeMapX a -> TypeMapG (TypeMapG a)
forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_forall (TypeMapX a -> TypeMapG (TypeMapG a))
-> (TypeMapG (TypeMapG a) -> Maybe a) -> TypeMapX a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> Key TypeMapX -> TypeMapG (TypeMapG a) -> Maybe (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
tv) Type
ty)
                                               (TypeMapG (TypeMapG a) -> Maybe (TypeMapG a))
-> (TypeMapG a -> Maybe a) -> TypeMapG (TypeMapG a) -> Maybe a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> CmEnv -> Id -> TypeMapG a -> Maybe a
forall a. CmEnv -> Id -> BndrMap a -> Maybe a
lkBndr CmEnv
env Id
tv
    go ty :: Type
ty@(FunTy {})               = String -> SDoc -> TypeMapX a -> Maybe a
forall a. HasCallStack => String -> SDoc -> a
pprPanic "lkT FunTy" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
    go (CastTy t :: Type
t _)                = Type -> TypeMapX a -> Maybe a
go Type
t
    go (CoercionTy {})             = TypeMapX a -> Maybe a
forall a. TypeMapX a -> Maybe a
tm_coerce

-----------------
xtT :: DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
xtT :: DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
xtT (D env :: CmEnv
env ty :: Type
ty) f :: XT a
f m :: TypeMapX a
m | Just ty' :: Type
ty' <- Type -> Maybe Type
trieMapView Type
ty = DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
forall a. DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
xtT (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
ty') XT a
f TypeMapX a
m

xtT (D env :: CmEnv
env (TyVarTy v :: Id
v))       f :: XT a
f m :: TypeMapX a
m = TypeMapX a
m { tm_var :: VarMap a
tm_var    = TypeMapX a -> VarMap a
forall a. TypeMapX a -> VarMap a
tm_var TypeMapX a
m VarMap a -> (VarMap a -> VarMap a) -> VarMap a
forall a b. a -> (a -> b) -> b
|> CmEnv -> Id -> XT a -> VarMap a -> VarMap a
forall a. CmEnv -> Id -> XT a -> VarMap a -> VarMap a
xtVar CmEnv
env Id
v XT a
f }
xtT (D env :: CmEnv
env (AppTy t1 :: Type
t1 t2 :: Type
t2))     f :: XT a
f m :: TypeMapX a
m = TypeMapX a
m { tm_app :: TypeMapG (TypeMapG a)
tm_app    = TypeMapX a -> TypeMapG (TypeMapG a)
forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_app TypeMapX a
m TypeMapG (TypeMapG a)
-> (TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG a))
-> TypeMapG (TypeMapG a)
forall a b. a -> (a -> b) -> b
|> Key TypeMapX
-> XT (TypeMapG a)
-> TypeMapG (TypeMapG a)
-> TypeMapG (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t1)
                                                            (XT (TypeMapG a) -> TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG a))
-> (TypeMapG a -> TypeMapG a)
-> TypeMapG (TypeMapG a)
-> TypeMapG (TypeMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key TypeMapX -> XT a -> TypeMapG a -> TypeMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t2) XT a
f }
xtT (D _   (TyConApp tc :: TyCon
tc []))  f :: XT a
f m :: TypeMapX a
m = TypeMapX a
m { tm_tycon :: DNameEnv a
tm_tycon  = TypeMapX a -> DNameEnv a
forall a. TypeMapX a -> DNameEnv a
tm_tycon TypeMapX a
m DNameEnv a -> (DNameEnv a -> DNameEnv a) -> DNameEnv a
forall a b. a -> (a -> b) -> b
|> TyCon -> XT a -> DNameEnv a -> DNameEnv a
forall n a. NamedThing n => n -> XT a -> DNameEnv a -> DNameEnv a
xtDNamed TyCon
tc XT a
f }
xtT (D _   (LitTy l :: TyLit
l))         f :: XT a
f m :: TypeMapX a
m = TypeMapX a
m { tm_tylit :: TyLitMap a
tm_tylit  = TypeMapX a -> TyLitMap a
forall a. TypeMapX a -> TyLitMap a
tm_tylit TypeMapX a
m TyLitMap a -> (TyLitMap a -> TyLitMap a) -> TyLitMap a
forall a b. a -> (a -> b) -> b
|> TyLit -> XT a -> TyLitMap a -> TyLitMap a
forall a. TyLit -> XT a -> TyLitMap a -> TyLitMap a
xtTyLit TyLit
l XT a
f }
xtT (D env :: CmEnv
env (CastTy t :: Type
t _))      f :: XT a
f m :: TypeMapX a
m = DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
forall a. DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a
xtT (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
t) XT a
f TypeMapX a
m
xtT (D _   (CoercionTy {}))   f :: XT a
f m :: TypeMapX a
m = TypeMapX a
m { tm_coerce :: Maybe a
tm_coerce = TypeMapX a -> Maybe a
forall a. TypeMapX a -> Maybe a
tm_coerce TypeMapX a
m Maybe a -> XT a -> Maybe a
forall a b. a -> (a -> b) -> b
|> XT a
f }
xtT (D env :: CmEnv
env (ForAllTy (Bndr tv :: Id
tv _) ty :: Type
ty))  f :: XT a
f m :: TypeMapX a
m
  = TypeMapX a
m { tm_forall :: TypeMapG (TypeMapG a)
tm_forall = TypeMapX a -> TypeMapG (TypeMapG a)
forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_forall TypeMapX a
m TypeMapG (TypeMapG a)
-> (TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG a))
-> TypeMapG (TypeMapG a)
forall a b. a -> (a -> b) -> b
|> Key TypeMapX
-> XT (TypeMapG a)
-> TypeMapG (TypeMapG a)
-> TypeMapG (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D (CmEnv -> Id -> CmEnv
extendCME CmEnv
env Id
tv) Type
ty)
                                (XT (TypeMapG a) -> TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG a))
-> (TypeMapG a -> TypeMapG a)
-> TypeMapG (TypeMapG a)
-> TypeMapG (TypeMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> CmEnv -> Id -> XT a -> TypeMapG a -> TypeMapG a
forall a. CmEnv -> Id -> XT a -> BndrMap a -> BndrMap a
xtBndr CmEnv
env Id
tv XT a
f }
xtT (D _   ty :: Type
ty@(TyConApp _ (_:_))) _ _ = String -> SDoc -> TypeMapX a
forall a. HasCallStack => String -> SDoc -> a
pprPanic "xtT TyConApp" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
xtT (D _   ty :: Type
ty@(FunTy {}))         _ _ = String -> SDoc -> TypeMapX a
forall a. HasCallStack => String -> SDoc -> a
pprPanic "xtT FunTy" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)

fdT :: (a -> b -> b) -> TypeMapX a -> b -> b
fdT :: (a -> b -> b) -> TypeMapX a -> b -> b
fdT k :: a -> b -> b
k m :: TypeMapX a
m = (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 (TypeMapX a -> VarMap a
forall a. TypeMapX a -> VarMap a
tm_var TypeMapX a
m)
        (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenMap TypeMapX a -> b -> b)
-> GenMap TypeMapX (GenMap TypeMapX 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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k) (TypeMapX a -> GenMap TypeMapX (GenMap TypeMapX a)
forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_app TypeMapX a
m)
        (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> b) -> UniqDFM a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k (TypeMapX a -> UniqDFM a
forall a. TypeMapX a -> DNameEnv a
tm_tycon TypeMapX a
m)
        (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenMap TypeMapX a -> b -> b)
-> GenMap TypeMapX (GenMap TypeMapX 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 (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k) (TypeMapX a -> GenMap TypeMapX (GenMap TypeMapX a)
forall a. TypeMapX a -> TypeMapG (TypeMapG a)
tm_forall TypeMapX a
m)
        (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> b) -> TyLitMap a -> b -> b
forall a b. (a -> b -> b) -> TyLitMap a -> b -> b
foldTyLit a -> b -> b
k (TypeMapX a -> TyLitMap a
forall a. TypeMapX a -> TyLitMap a
tm_tylit TypeMapX a
m)
        (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> b) -> Maybe a -> b -> b
forall a b. (a -> b -> b) -> Maybe a -> b -> b
foldMaybe a -> b -> b
k (TypeMapX a -> Maybe a
forall a. TypeMapX a -> Maybe a
tm_coerce TypeMapX a
m)

------------------------
data TyLitMap a = TLM { TyLitMap a -> Map Integer a
tlm_number :: Map.Map Integer a
                      , TyLitMap a -> Map FastString a
tlm_string :: Map.Map FastString a
                      }

instance TrieMap TyLitMap where
   type Key TyLitMap = TyLit
   emptyTM :: TyLitMap a
emptyTM  = TyLitMap a
forall a. TyLitMap a
emptyTyLitMap
   lookupTM :: Key TyLitMap -> TyLitMap b -> Maybe b
lookupTM = Key TyLitMap -> TyLitMap b -> Maybe b
forall a. TyLit -> TyLitMap a -> Maybe a
lkTyLit
   alterTM :: Key TyLitMap -> XT b -> TyLitMap b -> TyLitMap b
alterTM  = Key TyLitMap -> XT b -> TyLitMap b -> TyLitMap b
forall a. TyLit -> XT a -> TyLitMap a -> TyLitMap a
xtTyLit
   foldTM :: (a -> b -> b) -> TyLitMap a -> b -> b
foldTM   = (a -> b -> b) -> TyLitMap a -> b -> b
forall a b. (a -> b -> b) -> TyLitMap a -> b -> b
foldTyLit
   mapTM :: (a -> b) -> TyLitMap a -> TyLitMap b
mapTM    = (a -> b) -> TyLitMap a -> TyLitMap b
forall a b. (a -> b) -> TyLitMap a -> TyLitMap b
mapTyLit

emptyTyLitMap :: TyLitMap a
emptyTyLitMap :: TyLitMap a
emptyTyLitMap = TLM :: forall a. Map Integer a -> Map FastString a -> TyLitMap a
TLM { tlm_number :: Map Integer a
tlm_number = Map Integer a
forall k a. Map k a
Map.empty, tlm_string :: Map FastString a
tlm_string = Map FastString a
forall k a. Map k a
Map.empty }

mapTyLit :: (a->b) -> TyLitMap a -> TyLitMap b
mapTyLit :: (a -> b) -> TyLitMap a -> TyLitMap b
mapTyLit f :: a -> b
f (TLM { tlm_number :: forall a. TyLitMap a -> Map Integer a
tlm_number = Map Integer a
tn, tlm_string :: forall a. TyLitMap a -> Map FastString a
tlm_string = Map FastString a
ts })
  = TLM :: forall a. Map Integer a -> Map FastString a -> TyLitMap a
TLM { tlm_number :: Map Integer b
tlm_number = (a -> b) -> Map Integer a -> Map Integer b
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map a -> b
f Map Integer a
tn, tlm_string :: Map FastString b
tlm_string = (a -> b) -> Map FastString a -> Map FastString b
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map a -> b
f Map FastString a
ts }

lkTyLit :: TyLit -> TyLitMap a -> Maybe a
lkTyLit :: TyLit -> TyLitMap a -> Maybe a
lkTyLit l :: TyLit
l =
  case TyLit
l of
    NumTyLit n :: Integer
n -> TyLitMap a -> Map Integer a
forall a. TyLitMap a -> Map Integer a
tlm_number (TyLitMap a -> Map Integer a)
-> (Map Integer a -> Maybe a) -> TyLitMap a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> Integer -> Map Integer a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Integer
n
    StrTyLit n :: FastString
n -> TyLitMap a -> Map FastString a
forall a. TyLitMap a -> Map FastString a
tlm_string (TyLitMap a -> Map FastString a)
-> (Map FastString a -> Maybe a) -> TyLitMap a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> FastString -> Map FastString a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FastString
n

xtTyLit :: TyLit -> XT a -> TyLitMap a -> TyLitMap a
xtTyLit :: TyLit -> XT a -> TyLitMap a -> TyLitMap a
xtTyLit l :: TyLit
l f :: XT a
f m :: TyLitMap a
m =
  case TyLit
l of
    NumTyLit n :: Integer
n -> TyLitMap a
m { tlm_number :: Map Integer a
tlm_number = TyLitMap a -> Map Integer a
forall a. TyLitMap a -> Map Integer a
tlm_number TyLitMap a
m Map Integer a -> (Map Integer a -> Map Integer a) -> Map Integer a
forall a b. a -> (a -> b) -> b
|> XT a -> Integer -> Map Integer a -> Map Integer a
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter XT a
f Integer
n }
    StrTyLit n :: FastString
n -> TyLitMap a
m { tlm_string :: Map FastString a
tlm_string = TyLitMap a -> Map FastString a
forall a. TyLitMap a -> Map FastString a
tlm_string TyLitMap a
m Map FastString a
-> (Map FastString a -> Map FastString a) -> Map FastString a
forall a b. a -> (a -> b) -> b
|> XT a -> FastString -> Map FastString a -> Map FastString a
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter XT a
f FastString
n }

foldTyLit :: (a -> b -> b) -> TyLitMap a -> b -> b
foldTyLit :: (a -> b -> b) -> TyLitMap a -> b -> b
foldTyLit l :: a -> b -> b
l m :: TyLitMap a
m = (b -> Map FastString a -> b) -> Map FastString a -> b -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((a -> b -> b) -> b -> Map FastString a -> b
forall a b k. (a -> b -> b) -> b -> Map k a -> b
Map.foldr a -> b -> b
l) (TyLitMap a -> Map FastString a
forall a. TyLitMap a -> Map FastString a
tlm_string TyLitMap a
m)
              (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> Map Integer a -> b) -> Map Integer a -> b -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((a -> b -> b) -> b -> Map Integer a -> b
forall a b k. (a -> b -> b) -> b -> Map k a -> b
Map.foldr a -> b -> b
l) (TyLitMap a -> Map Integer a
forall a. TyLitMap a -> Map Integer a
tlm_number TyLitMap a
m)

-------------------------------------------------
-- | @TypeMap a@ is a map from 'Type' to @a@.  If you are a client, this
-- is the type you want. The keys in this map may have different kinds.
newtype TypeMap a = TypeMap (TypeMapG (TypeMapG a))

lkTT :: DeBruijn Type -> TypeMap a -> Maybe a
lkTT :: DeBruijn Type -> TypeMap a -> Maybe a
lkTT (D env :: CmEnv
env ty :: Type
ty) (TypeMap m :: TypeMapG (TypeMapG a)
m) = Key TypeMapX -> TypeMapG (TypeMapG a) -> Maybe (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Type -> Key TypeMapX) -> Type -> Key TypeMapX
forall a b. (a -> b) -> a -> b
$ HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty) TypeMapG (TypeMapG a)
m
                          Maybe (TypeMapG a) -> (TypeMapG a -> Maybe a) -> Maybe a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Key TypeMapX -> TypeMapG a -> Maybe a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
ty)

xtTT :: DeBruijn Type -> XT a -> TypeMap a -> TypeMap a
xtTT :: DeBruijn Type -> XT a -> TypeMap a -> TypeMap a
xtTT (D env :: CmEnv
env ty :: Type
ty) f :: XT a
f (TypeMap m :: TypeMapG (TypeMapG a)
m)
  = TypeMapG (TypeMapG a) -> TypeMap a
forall a. TypeMapG (TypeMapG a) -> TypeMap a
TypeMap (TypeMapG (TypeMapG a)
m TypeMapG (TypeMapG a)
-> (TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG a))
-> TypeMapG (TypeMapG a)
forall a b. a -> (a -> b) -> b
|> Key TypeMapX
-> XT (TypeMapG a)
-> TypeMapG (TypeMapG a)
-> TypeMapG (TypeMapG a)
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Type -> Key TypeMapX) -> Type -> Key TypeMapX
forall a b. (a -> b) -> a -> b
$ HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty)
               (XT (TypeMapG a) -> TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG a))
-> (TypeMapG a -> TypeMapG a)
-> TypeMapG (TypeMapG a)
-> TypeMapG (TypeMapG a)
forall (m2 :: * -> *) a (m1 :: * -> *).
TrieMap m2 =>
(XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
-> (m2 a -> m2 a) -> m1 (m2 a) -> m1 (m2 a)
|>> Key TypeMapX -> XT a -> TypeMapG a -> TypeMapG a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env Type
ty) XT a
f)

-- Below are some client-oriented functions which operate on 'TypeMap'.

instance TrieMap TypeMap where
    type Key TypeMap = Type
    emptyTM :: TypeMap a
emptyTM = TypeMapG (TypeMapG a) -> TypeMap a
forall a. TypeMapG (TypeMapG a) -> TypeMap a
TypeMap TypeMapG (TypeMapG a)
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
    lookupTM :: Key TypeMap -> TypeMap b -> Maybe b
lookupTM k :: Key TypeMap
k m :: TypeMap b
m = DeBruijn Type -> TypeMap b -> Maybe b
forall a. DeBruijn Type -> TypeMap a -> Maybe a
lkTT (Type -> DeBruijn Type
forall a. a -> DeBruijn a
deBruijnize Type
Key TypeMap
k) TypeMap b
m
    alterTM :: Key TypeMap -> XT b -> TypeMap b -> TypeMap b
alterTM k :: Key TypeMap
k f :: XT b
f m :: TypeMap b
m = DeBruijn Type -> XT b -> TypeMap b -> TypeMap b
forall a. DeBruijn Type -> XT a -> TypeMap a -> TypeMap a
xtTT (Type -> DeBruijn Type
forall a. a -> DeBruijn a
deBruijnize Type
Key TypeMap
k) XT b
f TypeMap b
m
    foldTM :: (a -> b -> b) -> TypeMap a -> b -> b
foldTM k :: a -> b -> b
k (TypeMap m :: TypeMapG (TypeMapG a)
m) = (TypeMapG a -> b -> b) -> TypeMapG (TypeMapG a) -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM ((a -> b -> b) -> TypeMapG a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k) TypeMapG (TypeMapG a)
m
    mapTM :: (a -> b) -> TypeMap a -> TypeMap b
mapTM f :: a -> b
f (TypeMap m :: TypeMapG (TypeMapG a)
m) = TypeMapG (TypeMapG b) -> TypeMap b
forall a. TypeMapG (TypeMapG a) -> TypeMap a
TypeMap ((TypeMapG a -> TypeMapG b)
-> TypeMapG (TypeMapG a) -> TypeMapG (TypeMapG b)
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f) TypeMapG (TypeMapG a)
m)

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

emptyTypeMap :: TypeMap a
emptyTypeMap :: TypeMap a
emptyTypeMap = TypeMap a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM

lookupTypeMap :: TypeMap a -> Type -> Maybe a
lookupTypeMap :: TypeMap a -> Type -> Maybe a
lookupTypeMap cm :: TypeMap a
cm t :: Type
t = Key TypeMap -> TypeMap a -> Maybe a
forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM Type
Key TypeMap
t TypeMap a
cm

extendTypeMap :: TypeMap a -> Type -> a -> TypeMap a
extendTypeMap :: TypeMap a -> Type -> a -> TypeMap a
extendTypeMap m :: TypeMap a
m t :: Type
t v :: a
v = Key TypeMap -> XT a -> TypeMap a -> TypeMap a
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM Type
Key TypeMap
t (Maybe a -> XT a
forall a b. a -> b -> a
const (a -> Maybe a
forall a. a -> Maybe a
Just a
v)) TypeMap a
m

lookupTypeMapWithScope :: TypeMap a -> CmEnv -> Type -> Maybe a
lookupTypeMapWithScope :: TypeMap a -> CmEnv -> Type -> Maybe a
lookupTypeMapWithScope m :: TypeMap a
m cm :: CmEnv
cm t :: Type
t = DeBruijn Type -> TypeMap a -> Maybe a
forall a. DeBruijn Type -> TypeMap a -> Maybe a
lkTT (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
cm Type
t) TypeMap a
m

-- | Extend a 'TypeMap' with a type in the given context.
-- @extendTypeMapWithScope m (mkDeBruijnContext [a,b,c]) t v@ is equivalent to
-- @extendTypeMap m (forall a b c. t) v@, but allows reuse of the context over
-- multiple insertions.
extendTypeMapWithScope :: TypeMap a -> CmEnv -> Type -> a -> TypeMap a
extendTypeMapWithScope :: TypeMap a -> CmEnv -> Type -> a -> TypeMap a
extendTypeMapWithScope m :: TypeMap a
m cm :: CmEnv
cm t :: Type
t v :: a
v = DeBruijn Type -> XT a -> TypeMap a -> TypeMap a
forall a. DeBruijn Type -> XT a -> TypeMap a -> TypeMap a
xtTT (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
cm Type
t) (Maybe a -> XT a
forall a b. a -> b -> a
const (a -> Maybe a
forall a. a -> Maybe a
Just a
v)) TypeMap a
m

-- | Construct a deBruijn environment with the given variables in scope.
-- e.g. @mkDeBruijnEnv [a,b,c]@ constructs a context @forall a b c.@
mkDeBruijnContext :: [Var] -> CmEnv
mkDeBruijnContext :: [Id] -> CmEnv
mkDeBruijnContext = CmEnv -> [Id] -> CmEnv
extendCMEs CmEnv
emptyCME

-- | A 'LooseTypeMap' doesn't do a kind-check. Thus, when lookup up (t |> g),
-- you'll find entries inserted under (t), even if (g) is non-reflexive.
newtype LooseTypeMap a
  = LooseTypeMap (TypeMapG a)

instance TrieMap LooseTypeMap where
  type Key LooseTypeMap = Type
  emptyTM :: LooseTypeMap a
emptyTM = TypeMapG a -> LooseTypeMap a
forall a. TypeMapG a -> LooseTypeMap a
LooseTypeMap TypeMapG a
forall (m :: * -> *) a. TrieMap m => m a
emptyTM
  lookupTM :: Key LooseTypeMap -> LooseTypeMap b -> Maybe b
lookupTM k :: Key LooseTypeMap
k (LooseTypeMap m :: TypeMapG b
m) = Key BndrMap -> TypeMapG b -> Maybe b
forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM (Type -> DeBruijn Type
forall a. a -> DeBruijn a
deBruijnize Type
Key LooseTypeMap
k) TypeMapG b
m
  alterTM :: Key LooseTypeMap -> XT b -> LooseTypeMap b -> LooseTypeMap b
alterTM k :: Key LooseTypeMap
k f :: XT b
f (LooseTypeMap m :: TypeMapG b
m) = TypeMapG b -> LooseTypeMap b
forall a. TypeMapG a -> LooseTypeMap a
LooseTypeMap (Key BndrMap -> XT b -> TypeMapG b -> TypeMapG b
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM (Type -> DeBruijn Type
forall a. a -> DeBruijn a
deBruijnize Type
Key LooseTypeMap
k) XT b
f TypeMapG b
m)
  foldTM :: (a -> b -> b) -> LooseTypeMap a -> b -> b
foldTM f :: a -> b -> b
f (LooseTypeMap m :: TypeMapG a
m) = (a -> b -> b) -> TypeMapG a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
f TypeMapG a
m
  mapTM :: (a -> b) -> LooseTypeMap a -> LooseTypeMap b
mapTM f :: a -> b
f (LooseTypeMap m :: TypeMapG a
m) = TypeMapG b -> LooseTypeMap b
forall a. TypeMapG a -> LooseTypeMap a
LooseTypeMap ((a -> b) -> TypeMapG a -> TypeMapG b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f TypeMapG a
m)

{-
************************************************************************
*                                                                      *
                   Variables
*                                                                      *
************************************************************************
-}

type BoundVar = Int  -- Bound variables are deBruijn numbered
type BoundVarMap a = IntMap.IntMap a

data CmEnv = CME { CmEnv -> BoundVar
cme_next :: !BoundVar
                 , CmEnv -> VarEnv BoundVar
cme_env  :: VarEnv BoundVar }

emptyCME :: CmEnv
emptyCME :: CmEnv
emptyCME = $WCME :: BoundVar -> VarEnv BoundVar -> CmEnv
CME { cme_next :: BoundVar
cme_next = 0, cme_env :: VarEnv BoundVar
cme_env = VarEnv BoundVar
forall a. VarEnv a
emptyVarEnv }

extendCME :: CmEnv -> Var -> CmEnv
extendCME :: CmEnv -> Id -> CmEnv
extendCME (CME { cme_next :: CmEnv -> BoundVar
cme_next = BoundVar
bv, cme_env :: CmEnv -> VarEnv BoundVar
cme_env = VarEnv BoundVar
env }) v :: Id
v
  = $WCME :: BoundVar -> VarEnv BoundVar -> CmEnv
CME { cme_next :: BoundVar
cme_next = BoundVar
bvBoundVar -> BoundVar -> BoundVar
forall a. Num a => a -> a -> a
+1, cme_env :: VarEnv BoundVar
cme_env = VarEnv BoundVar -> Id -> BoundVar -> VarEnv BoundVar
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv VarEnv BoundVar
env Id
v BoundVar
bv }

extendCMEs :: CmEnv -> [Var] -> CmEnv
extendCMEs :: CmEnv -> [Id] -> CmEnv
extendCMEs env :: CmEnv
env vs :: [Id]
vs = (CmEnv -> Id -> CmEnv) -> CmEnv -> [Id] -> CmEnv
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' CmEnv -> Id -> CmEnv
extendCME CmEnv
env [Id]
vs

lookupCME :: CmEnv -> Var -> Maybe BoundVar
lookupCME :: CmEnv -> Id -> Maybe BoundVar
lookupCME (CME { cme_env :: CmEnv -> VarEnv BoundVar
cme_env = VarEnv BoundVar
env }) v :: Id
v = VarEnv BoundVar -> Id -> Maybe BoundVar
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv VarEnv BoundVar
env Id
v

-- | @DeBruijn a@ represents @a@ modulo alpha-renaming.  This is achieved
-- by equipping the value with a 'CmEnv', which tracks an on-the-fly deBruijn
-- numbering.  This allows us to define an 'Eq' instance for @DeBruijn a@, even
-- if this was not (easily) possible for @a@.  Note: we purposely don't
-- export the constructor.  Make a helper function if you find yourself
-- needing it.
data DeBruijn a = D CmEnv a

-- | Synthesizes a @DeBruijn a@ from an @a@, by assuming that there are no
-- bound binders (an empty 'CmEnv').  This is usually what you want if there
-- isn't already a 'CmEnv' in scope.
deBruijnize :: a -> DeBruijn a
deBruijnize :: a -> DeBruijn a
deBruijnize = CmEnv -> a -> DeBruijn a
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
emptyCME

instance Eq (DeBruijn a) => Eq (DeBruijn [a]) where
    D _   []     == :: DeBruijn [a] -> DeBruijn [a] -> Bool
== D _    []       = Bool
True
    D env :: CmEnv
env (x :: a
x:xs :: [a]
xs) == D env' :: CmEnv
env' (x' :: a
x':xs' :: [a]
xs') = CmEnv -> a -> DeBruijn a
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env a
x  DeBruijn a -> DeBruijn a -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> a -> DeBruijn a
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' a
x' Bool -> Bool -> Bool
&&
                                      CmEnv -> [a] -> DeBruijn [a]
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env [a]
xs DeBruijn [a] -> DeBruijn [a] -> Bool
forall a. Eq a => a -> a -> Bool
== CmEnv -> [a] -> DeBruijn [a]
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env' [a]
xs'
    _            == _               = Bool
False

--------- Variable binders -------------

-- | A 'BndrMap' is a 'TypeMapG' which allows us to distinguish between
-- binding forms whose binders have different types.  For example,
-- if we are doing a 'TrieMap' lookup on @\(x :: Int) -> ()@, we should
-- not pick up an entry in the 'TrieMap' for @\(x :: Bool) -> ()@:
-- we can disambiguate this by matching on the type (or kind, if this
-- a binder in a type) of the binder.
type BndrMap = TypeMapG

-- Note [Binders]
-- ~~~~~~~~~~~~~~
-- We need to use 'BndrMap' for 'Coercion', 'CoreExpr' AND 'Type', since all
-- of these data types have binding forms.

lkBndr :: CmEnv -> Var -> BndrMap a -> Maybe a
lkBndr :: CmEnv -> Id -> BndrMap a -> Maybe a
lkBndr env :: CmEnv
env v :: Id
v m :: BndrMap a
m = Key TypeMapX -> BndrMap a -> Maybe a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> GenMap m a -> Maybe a
lkG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Id -> Type
varType Id
v)) BndrMap a
m

xtBndr :: CmEnv -> Var -> XT a -> BndrMap a -> BndrMap a
xtBndr :: CmEnv -> Id -> XT a -> BndrMap a -> BndrMap a
xtBndr env :: CmEnv
env v :: Id
v f :: XT a
f = Key TypeMapX -> XT a -> BndrMap a -> BndrMap a
forall (m :: * -> *) a.
(Eq (Key m), TrieMap m) =>
Key m -> XT a -> GenMap m a -> GenMap m a
xtG (CmEnv -> Type -> DeBruijn Type
forall a. CmEnv -> a -> DeBruijn a
D CmEnv
env (Id -> Type
varType Id
v)) XT a
f

--------- Variable occurrence -------------
data VarMap a = VM { VarMap a -> BoundVarMap a
vm_bvar   :: BoundVarMap a  -- Bound variable
                   , VarMap a -> DVarEnv a
vm_fvar   :: DVarEnv a }      -- Free variable

instance TrieMap VarMap where
   type Key VarMap = Var
   emptyTM :: VarMap a
emptyTM  = VM :: forall a. BoundVarMap a -> DVarEnv a -> VarMap a
VM { vm_bvar :: BoundVarMap a
vm_bvar = BoundVarMap a
forall a. IntMap a
IntMap.empty, vm_fvar :: DVarEnv a
vm_fvar = DVarEnv a
forall a. DNameEnv a
emptyDVarEnv }
   lookupTM :: Key VarMap -> VarMap b -> Maybe b
lookupTM = CmEnv -> Id -> VarMap b -> Maybe b
forall a. CmEnv -> Id -> VarMap a -> Maybe a
lkVar CmEnv
emptyCME
   alterTM :: Key VarMap -> XT b -> VarMap b -> VarMap b
alterTM  = CmEnv -> Id -> XT b -> VarMap b -> VarMap b
forall a. CmEnv -> Id -> XT a -> VarMap a -> VarMap a
xtVar CmEnv
emptyCME
   foldTM :: (a -> b -> b) -> VarMap a -> b -> b
foldTM   = (a -> b -> b) -> VarMap a -> b -> b
forall a b. (a -> b -> b) -> VarMap a -> b -> b
fdVar
   mapTM :: (a -> b) -> VarMap a -> VarMap b
mapTM    = (a -> b) -> VarMap a -> VarMap b
forall a b. (a -> b) -> VarMap a -> VarMap b
mapVar

mapVar :: (a->b) -> VarMap a -> VarMap b
mapVar :: (a -> b) -> VarMap a -> VarMap b
mapVar f :: a -> b
f (VM { vm_bvar :: forall a. VarMap a -> BoundVarMap a
vm_bvar = BoundVarMap a
bv, vm_fvar :: forall a. VarMap a -> DVarEnv a
vm_fvar = DVarEnv a
fv })
  = VM :: forall a. BoundVarMap a -> DVarEnv a -> VarMap a
VM { vm_bvar :: BoundVarMap b
vm_bvar = (a -> b) -> BoundVarMap a -> BoundVarMap b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f BoundVarMap a
bv, vm_fvar :: DVarEnv b
vm_fvar = (a -> b) -> DVarEnv a -> DVarEnv b
forall (m :: * -> *) a b. TrieMap m => (a -> b) -> m a -> m b
mapTM a -> b
f DVarEnv a
fv }

lkVar :: CmEnv -> Var -> VarMap a -> Maybe a
lkVar :: CmEnv -> Id -> VarMap a -> Maybe a
lkVar env :: CmEnv
env v :: Id
v
  | Just bv :: BoundVar
bv <- CmEnv -> Id -> Maybe BoundVar
lookupCME CmEnv
env Id
v = VarMap a -> BoundVarMap a
forall a. VarMap a -> BoundVarMap a
vm_bvar (VarMap a -> BoundVarMap a)
-> (BoundVarMap a -> Maybe a) -> VarMap a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> Key IntMap -> BoundVarMap a -> Maybe a
forall (m :: * -> *) b. TrieMap m => Key m -> m b -> Maybe b
lookupTM BoundVar
Key IntMap
bv
  | Bool
otherwise                  = VarMap a -> DVarEnv a
forall a. VarMap a -> DVarEnv a
vm_fvar (VarMap a -> DVarEnv a)
-> (DVarEnv a -> Maybe a) -> VarMap a -> Maybe a
forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> Id -> DVarEnv a -> Maybe a
forall a. Id -> DVarEnv a -> Maybe a
lkDFreeVar Id
v

xtVar :: CmEnv -> Var -> XT a -> VarMap a -> VarMap a
xtVar :: CmEnv -> Id -> XT a -> VarMap a -> VarMap a
xtVar env :: CmEnv
env v :: Id
v f :: XT a
f m :: VarMap a
m
  | Just bv :: BoundVar
bv <- CmEnv -> Id -> Maybe BoundVar
lookupCME CmEnv
env Id
v = VarMap a
m { vm_bvar :: BoundVarMap a
vm_bvar = VarMap a -> BoundVarMap a
forall a. VarMap a -> BoundVarMap a
vm_bvar VarMap a
m BoundVarMap a -> (BoundVarMap a -> BoundVarMap a) -> BoundVarMap a
forall a b. a -> (a -> b) -> b
|> Key IntMap -> XT a -> BoundVarMap a -> BoundVarMap a
forall (m :: * -> *) b. TrieMap m => Key m -> XT b -> m b -> m b
alterTM BoundVar
Key IntMap
bv XT a
f }
  | Bool
otherwise                  = VarMap a
m { vm_fvar :: DVarEnv a
vm_fvar = VarMap a -> DVarEnv a
forall a. VarMap a -> DVarEnv a
vm_fvar VarMap a
m DVarEnv a -> (DVarEnv a -> DVarEnv a) -> DVarEnv a
forall a b. a -> (a -> b) -> b
|> Id -> XT a -> DVarEnv a -> DVarEnv a
forall a. Id -> XT a -> DVarEnv a -> DVarEnv a
xtDFreeVar Id
v XT a
f }

fdVar :: (a -> b -> b) -> VarMap a -> b -> b
fdVar :: (a -> b -> b) -> VarMap a -> b -> b
fdVar k :: a -> b -> b
k m :: VarMap a
m = (a -> b -> b) -> IntMap a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k (VarMap a -> IntMap a
forall a. VarMap a -> BoundVarMap a
vm_bvar VarMap a
m)
          (b -> b) -> (b -> b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> b) -> UniqDFM a -> b -> b
forall (m :: * -> *) a b.
TrieMap m =>
(a -> b -> b) -> m a -> b -> b
foldTM a -> b -> b
k (VarMap a -> UniqDFM a
forall a. VarMap a -> DVarEnv a
vm_fvar VarMap a
m)

lkDFreeVar :: Var -> DVarEnv a -> Maybe a
lkDFreeVar :: Id -> DVarEnv a -> Maybe a
lkDFreeVar var :: Id
var env :: DVarEnv a
env = DVarEnv a -> Id -> Maybe a
forall a. DVarEnv a -> Id -> Maybe a
lookupDVarEnv DVarEnv a
env Id
var

xtDFreeVar :: Var -> XT a -> DVarEnv a -> DVarEnv a
xtDFreeVar :: Id -> XT a -> DVarEnv a -> DVarEnv a
xtDFreeVar v :: Id
v f :: XT a
f m :: DVarEnv a
m = XT a -> DVarEnv a -> Id -> DVarEnv a
forall a. (Maybe a -> Maybe a) -> DVarEnv a -> Id -> DVarEnv a
alterDVarEnv XT a
f DVarEnv a
m Id
v