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

\section[TyConEnv]{@TyConEnv@: tyCon environments}
-}


{-# LANGUAGE ScopedTypeVariables #-}


module GHC.Core.TyCon.Env (
        -- * TyCon environment (map)
        TyConEnv,

        -- ** Manipulating these environments
        mkTyConEnv, mkTyConEnvWith,
        emptyTyConEnv, isEmptyTyConEnv,
        unitTyConEnv, nonDetTyConEnvElts,
        extendTyConEnv_C, extendTyConEnv_Acc, extendTyConEnv,
        extendTyConEnvList, extendTyConEnvList_C,
        filterTyConEnv, anyTyConEnv,
        plusTyConEnv, plusTyConEnv_C, plusTyConEnv_CD, plusTyConEnv_CD2, alterTyConEnv,
        lookupTyConEnv, lookupTyConEnv_NF, delFromTyConEnv, delListFromTyConEnv,
        elemTyConEnv, mapTyConEnv, disjointTyConEnv,

        DTyConEnv,

        emptyDTyConEnv, isEmptyDTyConEnv,
        lookupDTyConEnv,
        delFromDTyConEnv, filterDTyConEnv,
        mapDTyConEnv, mapMaybeDTyConEnv,
        adjustDTyConEnv, alterDTyConEnv, extendDTyConEnv, foldDTyConEnv
    ) where

import GHC.Prelude

import GHC.Types.Unique.FM
import GHC.Types.Unique.DFM
import GHC.Core.TyCon (TyCon)

import GHC.Data.Maybe

{-
************************************************************************
*                                                                      *
\subsection{TyCon environment}
*                                                                      *
************************************************************************
-}

-- | TyCon Environment
type TyConEnv a = UniqFM TyCon a       -- Domain is TyCon

emptyTyConEnv       :: TyConEnv a
isEmptyTyConEnv     :: TyConEnv a -> Bool
mkTyConEnv          :: [(TyCon,a)] -> TyConEnv a
mkTyConEnvWith      :: (a -> TyCon) -> [a] -> TyConEnv a
nonDetTyConEnvElts  :: TyConEnv a -> [a]
alterTyConEnv       :: (Maybe a-> Maybe a) -> TyConEnv a -> TyCon -> TyConEnv a
extendTyConEnv_C    :: (a->a->a) -> TyConEnv a -> TyCon -> a -> TyConEnv a
extendTyConEnv_Acc  :: (a->b->b) -> (a->b) -> TyConEnv b -> TyCon -> a -> TyConEnv b
extendTyConEnv      :: TyConEnv a -> TyCon -> a -> TyConEnv a
plusTyConEnv        :: TyConEnv a -> TyConEnv a -> TyConEnv a
plusTyConEnv_C      :: (a->a->a) -> TyConEnv a -> TyConEnv a -> TyConEnv a
plusTyConEnv_CD     :: (a->a->a) -> TyConEnv a -> a -> TyConEnv a -> a -> TyConEnv a
plusTyConEnv_CD2    :: (Maybe a->Maybe a->a) -> TyConEnv a -> TyConEnv a -> TyConEnv a
extendTyConEnvList  :: TyConEnv a -> [(TyCon,a)] -> TyConEnv a
extendTyConEnvList_C :: (a->a->a) -> TyConEnv a -> [(TyCon,a)] -> TyConEnv a
delFromTyConEnv     :: TyConEnv a -> TyCon -> TyConEnv a
delListFromTyConEnv :: TyConEnv a -> [TyCon] -> TyConEnv a
elemTyConEnv        :: TyCon -> TyConEnv a -> Bool
unitTyConEnv        :: TyCon -> a -> TyConEnv a
lookupTyConEnv      :: TyConEnv a -> TyCon -> Maybe a
lookupTyConEnv_NF   :: TyConEnv a -> TyCon -> a
filterTyConEnv      :: (elt -> Bool) -> TyConEnv elt -> TyConEnv elt
anyTyConEnv         :: (elt -> Bool) -> TyConEnv elt -> Bool
mapTyConEnv         :: (elt1 -> elt2) -> TyConEnv elt1 -> TyConEnv elt2
disjointTyConEnv    :: TyConEnv a -> TyConEnv a -> Bool

nonDetTyConEnvElts :: forall a. TyConEnv a -> [a]
nonDetTyConEnvElts TyConEnv a
x   = TyConEnv a -> [a]
forall {k} (key :: k) elt. UniqFM key elt -> [elt]
nonDetEltsUFM TyConEnv a
x
emptyTyConEnv :: forall a. TyConEnv a
emptyTyConEnv          = UniqFM TyCon a
forall {k} (key :: k) elt. UniqFM key elt
emptyUFM
isEmptyTyConEnv :: forall a. TyConEnv a -> Bool
isEmptyTyConEnv        = UniqFM TyCon a -> Bool
forall {k} (key :: k) elt. UniqFM key elt -> Bool
isNullUFM
unitTyConEnv :: forall a. TyCon -> a -> TyConEnv a
unitTyConEnv TyCon
x a
y       = TyCon -> a -> UniqFM TyCon a
forall key elt. Uniquable key => key -> elt -> UniqFM key elt
unitUFM TyCon
x a
y
extendTyConEnv :: forall a. TyConEnv a -> TyCon -> a -> TyConEnv a
extendTyConEnv TyConEnv a
x TyCon
y a
z   = TyConEnv a -> TyCon -> a -> TyConEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM TyConEnv a
x TyCon
y a
z
extendTyConEnvList :: forall a. TyConEnv a -> [(TyCon, a)] -> TyConEnv a
extendTyConEnvList TyConEnv a
x [(TyCon, a)]
l = TyConEnv a -> [(TyCon, a)] -> TyConEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> [(key, elt)] -> UniqFM key elt
addListToUFM TyConEnv a
x [(TyCon, a)]
l
lookupTyConEnv :: forall a. TyConEnv a -> TyCon -> Maybe a
lookupTyConEnv TyConEnv a
x TyCon
y     = TyConEnv a -> TyCon -> Maybe a
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM TyConEnv a
x TyCon
y
alterTyConEnv :: forall a. (Maybe a -> Maybe a) -> TyConEnv a -> TyCon -> TyConEnv a
alterTyConEnv          = (Maybe a -> Maybe a) -> UniqFM TyCon a -> TyCon -> UniqFM TyCon a
forall key elt.
Uniquable key =>
(Maybe elt -> Maybe elt) -> UniqFM key elt -> key -> UniqFM key elt
alterUFM
mkTyConEnv :: forall a. [(TyCon, a)] -> TyConEnv a
mkTyConEnv     [(TyCon, a)]
l       = [(TyCon, a)] -> UniqFM TyCon a
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM [(TyCon, a)]
l
mkTyConEnvWith :: forall a. (a -> TyCon) -> [a] -> TyConEnv a
mkTyConEnvWith a -> TyCon
f       = [(TyCon, a)] -> TyConEnv a
forall a. [(TyCon, a)] -> TyConEnv a
mkTyConEnv ([(TyCon, a)] -> TyConEnv a)
-> ([a] -> [(TyCon, a)]) -> [a] -> TyConEnv a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (TyCon, a)) -> [a] -> [(TyCon, a)]
forall a b. (a -> b) -> [a] -> [b]
map (\a
a -> (a -> TyCon
f a
a, a
a))
elemTyConEnv :: forall a. TyCon -> TyConEnv a -> Bool
elemTyConEnv TyCon
x TyConEnv a
y          = TyCon -> TyConEnv a -> Bool
forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
elemUFM TyCon
x TyConEnv a
y
plusTyConEnv :: forall a. TyConEnv a -> TyConEnv a -> TyConEnv a
plusTyConEnv TyConEnv a
x TyConEnv a
y          = TyConEnv a -> TyConEnv a -> TyConEnv a
forall {k} (key :: k) elt.
UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM TyConEnv a
x TyConEnv a
y
plusTyConEnv_C :: forall a. (a -> a -> a) -> TyConEnv a -> TyConEnv a -> TyConEnv a
plusTyConEnv_C a -> a -> a
f TyConEnv a
x TyConEnv a
y      = (a -> a -> a) -> TyConEnv a -> TyConEnv a -> TyConEnv a
forall {k} elt (key :: k).
(elt -> elt -> elt)
-> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM_C a -> a -> a
f TyConEnv a
x TyConEnv a
y
plusTyConEnv_CD :: forall a.
(a -> a -> a) -> TyConEnv a -> a -> TyConEnv a -> a -> TyConEnv a
plusTyConEnv_CD a -> a -> a
f TyConEnv a
x a
d TyConEnv a
y a
b = (a -> a -> a) -> TyConEnv a -> a -> TyConEnv a -> a -> TyConEnv a
forall {k} elta eltb eltc (key :: k).
(elta -> eltb -> eltc)
-> UniqFM key elta
-> elta
-> UniqFM key eltb
-> eltb
-> UniqFM key eltc
plusUFM_CD a -> a -> a
f TyConEnv a
x a
d TyConEnv a
y a
b
plusTyConEnv_CD2 :: forall a.
(Maybe a -> Maybe a -> a) -> TyConEnv a -> TyConEnv a -> TyConEnv a
plusTyConEnv_CD2 Maybe a -> Maybe a -> a
f TyConEnv a
x TyConEnv a
y    = (Maybe a -> Maybe a -> a) -> TyConEnv a -> TyConEnv a -> TyConEnv a
forall {k} elta eltb eltc (key :: k).
(Maybe elta -> Maybe eltb -> eltc)
-> UniqFM key elta -> UniqFM key eltb -> UniqFM key eltc
plusUFM_CD2 Maybe a -> Maybe a -> a
f TyConEnv a
x TyConEnv a
y
extendTyConEnv_C :: forall a. (a -> a -> a) -> TyConEnv a -> TyCon -> a -> TyConEnv a
extendTyConEnv_C a -> a -> a
f TyConEnv a
x TyCon
y a
z  = (a -> a -> a) -> TyConEnv a -> TyCon -> a -> TyConEnv a
forall key elt.
Uniquable key =>
(elt -> elt -> elt)
-> UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM_C a -> a -> a
f TyConEnv a
x TyCon
y a
z
mapTyConEnv :: forall elt1 elt2. (elt1 -> elt2) -> TyConEnv elt1 -> TyConEnv elt2
mapTyConEnv elt1 -> elt2
f TyConEnv elt1
x           = (elt1 -> elt2) -> TyConEnv elt1 -> UniqFM TyCon elt2
forall {k} elt1 elt2 (key :: k).
(elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2
mapUFM elt1 -> elt2
f TyConEnv elt1
x
extendTyConEnv_Acc :: forall a b.
(a -> b -> b) -> (a -> b) -> TyConEnv b -> TyCon -> a -> TyConEnv b
extendTyConEnv_Acc a -> b -> b
x a -> b
y TyConEnv b
z TyCon
a a
b  = (a -> b -> b) -> (a -> b) -> TyConEnv b -> TyCon -> a -> TyConEnv b
forall key elt elts.
Uniquable key =>
(elt -> elts -> elts)
-> (elt -> elts)
-> UniqFM key elts
-> key
-> elt
-> UniqFM key elts
addToUFM_Acc a -> b -> b
x a -> b
y TyConEnv b
z TyCon
a a
b
extendTyConEnvList_C :: forall a. (a -> a -> a) -> TyConEnv a -> [(TyCon, a)] -> TyConEnv a
extendTyConEnvList_C a -> a -> a
x TyConEnv a
y [(TyCon, a)]
z = (a -> a -> a) -> TyConEnv a -> [(TyCon, a)] -> TyConEnv a
forall key elt.
Uniquable key =>
(elt -> elt -> elt)
-> UniqFM key elt -> [(key, elt)] -> UniqFM key elt
addListToUFM_C a -> a -> a
x TyConEnv a
y [(TyCon, a)]
z
delFromTyConEnv :: forall a. TyConEnv a -> TyCon -> TyConEnv a
delFromTyConEnv TyConEnv a
x TyCon
y      = TyConEnv a -> TyCon -> TyConEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> UniqFM key elt
delFromUFM TyConEnv a
x TyCon
y
delListFromTyConEnv :: forall a. TyConEnv a -> [TyCon] -> TyConEnv a
delListFromTyConEnv TyConEnv a
x [TyCon]
y  = TyConEnv a -> [TyCon] -> TyConEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> [key] -> UniqFM key elt
delListFromUFM TyConEnv a
x [TyCon]
y
filterTyConEnv :: forall elt. (elt -> Bool) -> TyConEnv elt -> TyConEnv elt
filterTyConEnv elt -> Bool
x TyConEnv elt
y       = (elt -> Bool) -> TyConEnv elt -> TyConEnv elt
forall {k} elt (key :: k).
(elt -> Bool) -> UniqFM key elt -> UniqFM key elt
filterUFM elt -> Bool
x TyConEnv elt
y
anyTyConEnv :: forall elt. (elt -> Bool) -> TyConEnv elt -> Bool
anyTyConEnv elt -> Bool
f TyConEnv elt
x          = (elt -> Bool -> Bool) -> Bool -> TyConEnv elt -> Bool
forall {k} elt a (key :: k).
(elt -> a -> a) -> a -> UniqFM key elt -> a
nonDetFoldUFM (Bool -> Bool -> Bool
(||) (Bool -> Bool -> Bool) -> (elt -> Bool) -> elt -> Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. elt -> Bool
f) Bool
False TyConEnv elt
x
disjointTyConEnv :: forall a. TyConEnv a -> TyConEnv a -> Bool
disjointTyConEnv TyConEnv a
x TyConEnv a
y     = TyConEnv a -> TyConEnv a -> Bool
forall {k} (key :: k) elt1 elt2.
UniqFM key elt1 -> UniqFM key elt2 -> Bool
disjointUFM TyConEnv a
x TyConEnv a
y

lookupTyConEnv_NF :: forall a. TyConEnv a -> TyCon -> a
lookupTyConEnv_NF TyConEnv a
env TyCon
n = String -> Maybe a -> a
forall a. HasCallStack => String -> Maybe a -> a
expectJust String
"lookupTyConEnv_NF" (TyConEnv a -> TyCon -> Maybe a
forall a. TyConEnv a -> TyCon -> Maybe a
lookupTyConEnv TyConEnv a
env TyCon
n)

-- | Deterministic TyCon Environment
--
-- See Note [Deterministic UniqFM] in "GHC.Types.Unique.DFM" for explanation why
-- we need DTyConEnv.
type DTyConEnv a = UniqDFM TyCon a

emptyDTyConEnv :: DTyConEnv a
emptyDTyConEnv :: forall a. DTyConEnv a
emptyDTyConEnv = UniqDFM TyCon a
forall {k} (key :: k) elt. UniqDFM key elt
emptyUDFM

isEmptyDTyConEnv :: DTyConEnv a -> Bool
isEmptyDTyConEnv :: forall a. DTyConEnv a -> Bool
isEmptyDTyConEnv = UniqDFM TyCon a -> Bool
forall {k} (key :: k) elt. UniqDFM key elt -> Bool
isNullUDFM

lookupDTyConEnv :: DTyConEnv a -> TyCon -> Maybe a
lookupDTyConEnv :: forall a. DTyConEnv a -> TyCon -> Maybe a
lookupDTyConEnv = UniqDFM TyCon a -> TyCon -> Maybe a
forall key elt.
Uniquable key =>
UniqDFM key elt -> key -> Maybe elt
lookupUDFM

delFromDTyConEnv :: DTyConEnv a -> TyCon -> DTyConEnv a
delFromDTyConEnv :: forall a. DTyConEnv a -> TyCon -> DTyConEnv a
delFromDTyConEnv = UniqDFM TyCon a -> TyCon -> UniqDFM TyCon a
forall key elt.
Uniquable key =>
UniqDFM key elt -> key -> UniqDFM key elt
delFromUDFM

filterDTyConEnv :: (a -> Bool) -> DTyConEnv a -> DTyConEnv a
filterDTyConEnv :: forall a. (a -> Bool) -> DTyConEnv a -> DTyConEnv a
filterDTyConEnv = (a -> Bool) -> UniqDFM TyCon a -> UniqDFM TyCon a
forall {k} elt (key :: k).
(elt -> Bool) -> UniqDFM key elt -> UniqDFM key elt
filterUDFM

mapDTyConEnv :: (a -> b) -> DTyConEnv a -> DTyConEnv b
mapDTyConEnv :: forall a b. (a -> b) -> DTyConEnv a -> DTyConEnv b
mapDTyConEnv = (a -> b) -> UniqDFM TyCon a -> UniqDFM TyCon b
forall {k} elt1 elt2 (key :: k).
(elt1 -> elt2) -> UniqDFM key elt1 -> UniqDFM key elt2
mapUDFM

mapMaybeDTyConEnv :: (a -> Maybe b) -> DTyConEnv a -> DTyConEnv b
mapMaybeDTyConEnv :: forall a b. (a -> Maybe b) -> DTyConEnv a -> DTyConEnv b
mapMaybeDTyConEnv = (a -> Maybe b) -> UniqDFM TyCon a -> UniqDFM TyCon b
forall {k} elt1 elt2 (key :: k).
(elt1 -> Maybe elt2) -> UniqDFM key elt1 -> UniqDFM key elt2
mapMaybeUDFM

adjustDTyConEnv :: (a -> a) -> DTyConEnv a -> TyCon -> DTyConEnv a
adjustDTyConEnv :: forall a. (a -> a) -> DTyConEnv a -> TyCon -> DTyConEnv a
adjustDTyConEnv = (a -> a) -> UniqDFM TyCon a -> TyCon -> UniqDFM TyCon a
forall key elt.
Uniquable key =>
(elt -> elt) -> UniqDFM key elt -> key -> UniqDFM key elt
adjustUDFM

alterDTyConEnv :: (Maybe a -> Maybe a) -> DTyConEnv a -> TyCon -> DTyConEnv a
alterDTyConEnv :: forall a.
(Maybe a -> Maybe a) -> DTyConEnv a -> TyCon -> DTyConEnv a
alterDTyConEnv = (Maybe a -> Maybe a) -> UniqDFM TyCon a -> TyCon -> UniqDFM TyCon a
forall key elt.
Uniquable key =>
(Maybe elt -> Maybe elt)
-> UniqDFM key elt -> key -> UniqDFM key elt
alterUDFM

extendDTyConEnv :: DTyConEnv a -> TyCon -> a -> DTyConEnv a
extendDTyConEnv :: forall a. DTyConEnv a -> TyCon -> a -> DTyConEnv a
extendDTyConEnv = UniqDFM TyCon a -> TyCon -> a -> UniqDFM TyCon a
forall key elt.
Uniquable key =>
UniqDFM key elt -> key -> elt -> UniqDFM key elt
addToUDFM

foldDTyConEnv :: (elt -> a -> a) -> a -> DTyConEnv elt -> a
foldDTyConEnv :: forall elt a. (elt -> a -> a) -> a -> DTyConEnv elt -> a
foldDTyConEnv = (elt -> a -> a) -> a -> UniqDFM TyCon elt -> a
forall {k} elt a (key :: k).
(elt -> a -> a) -> a -> UniqDFM key elt -> a
foldUDFM