Kill non-deterministic foldUFM in TrieMap and TcAppMap
[ghc.git] / compiler / basicTypes / VarEnv.hs
1 {-
2 (c) The University of Glasgow 2006
3 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 -}
5
6 module VarEnv (
7 -- * Var, Id and TyVar environments (maps)
8 VarEnv, IdEnv, TyVarEnv, CoVarEnv, TyCoVarEnv,
9
10 -- ** Manipulating these environments
11 emptyVarEnv, unitVarEnv, mkVarEnv, mkVarEnv_Directly,
12 elemVarEnv, varEnvElts, varEnvKeys, varEnvToList,
13 extendVarEnv, extendVarEnv_C, extendVarEnv_Acc, extendVarEnv_Directly,
14 extendVarEnvList,
15 plusVarEnv, plusVarEnv_C, plusVarEnv_CD, alterVarEnv,
16 delVarEnvList, delVarEnv, delVarEnv_Directly,
17 minusVarEnv, intersectsVarEnv,
18 lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv,
19 mapVarEnv, zipVarEnv,
20 modifyVarEnv, modifyVarEnv_Directly,
21 isEmptyVarEnv, foldVarEnv, foldVarEnv_Directly,
22 elemVarEnvByKey, lookupVarEnv_Directly,
23 filterVarEnv, filterVarEnv_Directly, restrictVarEnv,
24 partitionVarEnv,
25
26 -- * Deterministic Var environments (maps)
27 DVarEnv,
28
29 -- ** Manipulating these environments
30 emptyDVarEnv,
31 extendDVarEnv,
32 lookupDVarEnv,
33 foldDVarEnv,
34 mapDVarEnv,
35 alterDVarEnv,
36
37 -- * The InScopeSet type
38 InScopeSet,
39
40 -- ** Operations on InScopeSets
41 emptyInScopeSet, mkInScopeSet, delInScopeSet,
42 extendInScopeSet, extendInScopeSetList, extendInScopeSetSet,
43 getInScopeVars, lookupInScope, lookupInScope_Directly,
44 unionInScope, elemInScopeSet, uniqAway,
45 varSetInScope,
46
47 -- * The RnEnv2 type
48 RnEnv2,
49
50 -- ** Operations on RnEnv2s
51 mkRnEnv2, rnBndr2, rnBndrs2, rnBndr2_var,
52 rnOccL, rnOccR, inRnEnvL, inRnEnvR, rnOccL_maybe, rnOccR_maybe,
53 rnBndrL, rnBndrR, nukeRnEnvL, nukeRnEnvR, rnSwap,
54 delBndrL, delBndrR, delBndrsL, delBndrsR,
55 addRnInScopeSet,
56 rnEtaL, rnEtaR,
57 rnInScope, rnInScopeSet, lookupRnInScope,
58 rnEnvL, rnEnvR,
59
60 -- * TidyEnv and its operation
61 TidyEnv,
62 emptyTidyEnv
63 ) where
64
65 import OccName
66 import Var
67 import VarSet
68 import UniqFM
69 import UniqDFM
70 import Unique
71 import Util
72 import Maybes
73 import Outputable
74 import StaticFlags
75
76 {-
77 ************************************************************************
78 * *
79 In-scope sets
80 * *
81 ************************************************************************
82 -}
83
84 -- | A set of variables that are in scope at some point
85 -- "Secrets of the Glasgow Haskell Compiler inliner" Section 3. provides
86 -- the motivation for this abstraction.
87 data InScopeSet = InScope (VarEnv Var) {-# UNPACK #-} !Int
88 -- The (VarEnv Var) is just a VarSet. But we write it like
89 -- this to remind ourselves that you can look up a Var in
90 -- the InScopeSet. Typically the InScopeSet contains the
91 -- canonical version of the variable (e.g. with an informative
92 -- unfolding), so this lookup is useful.
93 --
94 -- INVARIANT: the VarEnv maps (the Unique of) a variable to
95 -- a variable with the same Unique. (This was not
96 -- the case in the past, when we had a grevious hack
97 -- mapping var1 to var2.
98 --
99 -- The Int is a kind of hash-value used by uniqAway
100 -- For example, it might be the size of the set
101 -- INVARIANT: it's not zero; we use it as a multiplier in uniqAway
102
103 instance Outputable InScopeSet where
104 ppr (InScope s _) = text "InScope"
105 <+> braces (fsep (map (ppr . Var.varName) (varSetElems s)))
106 -- In-scope sets get big, and with -dppr-debug
107 -- the output is overwhelming
108
109 emptyInScopeSet :: InScopeSet
110 emptyInScopeSet = InScope emptyVarSet 1
111
112 getInScopeVars :: InScopeSet -> VarEnv Var
113 getInScopeVars (InScope vs _) = vs
114
115 mkInScopeSet :: VarEnv Var -> InScopeSet
116 mkInScopeSet in_scope = InScope in_scope 1
117
118 extendInScopeSet :: InScopeSet -> Var -> InScopeSet
119 extendInScopeSet (InScope in_scope n) v = InScope (extendVarEnv in_scope v v) (n + 1)
120
121 extendInScopeSetList :: InScopeSet -> [Var] -> InScopeSet
122 extendInScopeSetList (InScope in_scope n) vs
123 = InScope (foldl (\s v -> extendVarEnv s v v) in_scope vs)
124 (n + length vs)
125
126 extendInScopeSetSet :: InScopeSet -> VarEnv Var -> InScopeSet
127 extendInScopeSetSet (InScope in_scope n) vs
128 = InScope (in_scope `plusVarEnv` vs) (n + sizeUFM vs)
129
130 delInScopeSet :: InScopeSet -> Var -> InScopeSet
131 delInScopeSet (InScope in_scope n) v = InScope (in_scope `delVarEnv` v) n
132
133 elemInScopeSet :: Var -> InScopeSet -> Bool
134 elemInScopeSet v (InScope in_scope _) = v `elemVarEnv` in_scope
135
136 -- | Look up a variable the 'InScopeSet'. This lets you map from
137 -- the variable's identity (unique) to its full value.
138 lookupInScope :: InScopeSet -> Var -> Maybe Var
139 lookupInScope (InScope in_scope _) v = lookupVarEnv in_scope v
140
141 lookupInScope_Directly :: InScopeSet -> Unique -> Maybe Var
142 lookupInScope_Directly (InScope in_scope _) uniq
143 = lookupVarEnv_Directly in_scope uniq
144
145 unionInScope :: InScopeSet -> InScopeSet -> InScopeSet
146 unionInScope (InScope s1 _) (InScope s2 n2)
147 = InScope (s1 `plusVarEnv` s2) n2
148
149 varSetInScope :: VarSet -> InScopeSet -> Bool
150 varSetInScope vars (InScope s1 _) = vars `subVarSet` s1
151
152 -- | @uniqAway in_scope v@ finds a unique that is not used in the
153 -- in-scope set, and gives that to v.
154 uniqAway :: InScopeSet -> Var -> Var
155 -- It starts with v's current unique, of course, in the hope that it won't
156 -- have to change, and thereafter uses a combination of that and the hash-code
157 -- found in the in-scope set
158 uniqAway in_scope var
159 | var `elemInScopeSet` in_scope = uniqAway' in_scope var -- Make a new one
160 | otherwise = var -- Nothing to do
161
162 uniqAway' :: InScopeSet -> Var -> Var
163 -- This one *always* makes up a new variable
164 uniqAway' (InScope set n) var
165 = try 1
166 where
167 orig_unique = getUnique var
168 try k
169 | debugIsOn && (k > 1000)
170 = pprPanic "uniqAway loop:" (ppr k <+> text "tries" <+> ppr var <+> int n)
171 | uniq `elemVarSetByKey` set = try (k + 1)
172 | debugIsOn && opt_PprStyle_Debug && (k > 3)
173 = pprTrace "uniqAway:" (ppr k <+> text "tries" <+> ppr var <+> int n)
174 setVarUnique var uniq
175 | otherwise = setVarUnique var uniq
176 where
177 uniq = deriveUnique orig_unique (n * k)
178
179 {-
180 ************************************************************************
181 * *
182 Dual renaming
183 * *
184 ************************************************************************
185 -}
186
187 -- | When we are comparing (or matching) types or terms, we are faced with
188 -- \"going under\" corresponding binders. E.g. when comparing:
189 --
190 -- > \x. e1 ~ \y. e2
191 --
192 -- Basically we want to rename [@x@ -> @y@] or [@y@ -> @x@], but there are lots of
193 -- things we must be careful of. In particular, @x@ might be free in @e2@, or
194 -- y in @e1@. So the idea is that we come up with a fresh binder that is free
195 -- in neither, and rename @x@ and @y@ respectively. That means we must maintain:
196 --
197 -- 1. A renaming for the left-hand expression
198 --
199 -- 2. A renaming for the right-hand expressions
200 --
201 -- 3. An in-scope set
202 --
203 -- Furthermore, when matching, we want to be able to have an 'occurs check',
204 -- to prevent:
205 --
206 -- > \x. f ~ \y. y
207 --
208 -- matching with [@f@ -> @y@]. So for each expression we want to know that set of
209 -- locally-bound variables. That is precisely the domain of the mappings 1.
210 -- and 2., but we must ensure that we always extend the mappings as we go in.
211 --
212 -- All of this information is bundled up in the 'RnEnv2'
213 data RnEnv2
214 = RV2 { envL :: VarEnv Var -- Renaming for Left term
215 , envR :: VarEnv Var -- Renaming for Right term
216 , in_scope :: InScopeSet } -- In scope in left or right terms
217
218 -- The renamings envL and envR are *guaranteed* to contain a binding
219 -- for every variable bound as we go into the term, even if it is not
220 -- renamed. That way we can ask what variables are locally bound
221 -- (inRnEnvL, inRnEnvR)
222
223 mkRnEnv2 :: InScopeSet -> RnEnv2
224 mkRnEnv2 vars = RV2 { envL = emptyVarEnv
225 , envR = emptyVarEnv
226 , in_scope = vars }
227
228 addRnInScopeSet :: RnEnv2 -> VarEnv Var -> RnEnv2
229 addRnInScopeSet env vs
230 | isEmptyVarEnv vs = env
231 | otherwise = env { in_scope = extendInScopeSetSet (in_scope env) vs }
232
233 rnInScope :: Var -> RnEnv2 -> Bool
234 rnInScope x env = x `elemInScopeSet` in_scope env
235
236 rnInScopeSet :: RnEnv2 -> InScopeSet
237 rnInScopeSet = in_scope
238
239 -- | Retrieve the left mapping
240 rnEnvL :: RnEnv2 -> VarEnv Var
241 rnEnvL = envL
242
243 -- | Retrieve the right mapping
244 rnEnvR :: RnEnv2 -> VarEnv Var
245 rnEnvR = envR
246
247 rnBndrs2 :: RnEnv2 -> [Var] -> [Var] -> RnEnv2
248 -- ^ Applies 'rnBndr2' to several variables: the two variable lists must be of equal length
249 rnBndrs2 env bsL bsR = foldl2 rnBndr2 env bsL bsR
250
251 rnBndr2 :: RnEnv2 -> Var -> Var -> RnEnv2
252 -- ^ @rnBndr2 env bL bR@ goes under a binder @bL@ in the Left term,
253 -- and binder @bR@ in the Right term.
254 -- It finds a new binder, @new_b@,
255 -- and returns an environment mapping @bL -> new_b@ and @bR -> new_b@
256 rnBndr2 env bL bR = fst $ rnBndr2_var env bL bR
257
258 rnBndr2_var :: RnEnv2 -> Var -> Var -> (RnEnv2, Var)
259 -- ^ Similar to 'rnBndr2' but returns the new variable as well as the
260 -- new environment
261 rnBndr2_var (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bL bR
262 = (RV2 { envL = extendVarEnv envL bL new_b -- See Note
263 , envR = extendVarEnv envR bR new_b -- [Rebinding]
264 , in_scope = extendInScopeSet in_scope new_b }, new_b)
265 where
266 -- Find a new binder not in scope in either term
267 new_b | not (bL `elemInScopeSet` in_scope) = bL
268 | not (bR `elemInScopeSet` in_scope) = bR
269 | otherwise = uniqAway' in_scope bL
270
271 -- Note [Rebinding]
272 -- If the new var is the same as the old one, note that
273 -- the extendVarEnv *deletes* any current renaming
274 -- E.g. (\x. \x. ...) ~ (\y. \z. ...)
275 --
276 -- Inside \x \y { [x->y], [y->y], {y} }
277 -- \x \z { [x->x], [y->y, z->x], {y,x} }
278
279 rnBndrL :: RnEnv2 -> Var -> (RnEnv2, Var)
280 -- ^ Similar to 'rnBndr2' but used when there's a binder on the left
281 -- side only.
282 rnBndrL (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bL
283 = (RV2 { envL = extendVarEnv envL bL new_b
284 , envR = envR
285 , in_scope = extendInScopeSet in_scope new_b }, new_b)
286 where
287 new_b = uniqAway in_scope bL
288
289 rnBndrR :: RnEnv2 -> Var -> (RnEnv2, Var)
290 -- ^ Similar to 'rnBndr2' but used when there's a binder on the right
291 -- side only.
292 rnBndrR (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bR
293 = (RV2 { envR = extendVarEnv envR bR new_b
294 , envL = envL
295 , in_scope = extendInScopeSet in_scope new_b }, new_b)
296 where
297 new_b = uniqAway in_scope bR
298
299 rnEtaL :: RnEnv2 -> Var -> (RnEnv2, Var)
300 -- ^ Similar to 'rnBndrL' but used for eta expansion
301 -- See Note [Eta expansion]
302 rnEtaL (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bL
303 = (RV2 { envL = extendVarEnv envL bL new_b
304 , envR = extendVarEnv envR new_b new_b -- Note [Eta expansion]
305 , in_scope = extendInScopeSet in_scope new_b }, new_b)
306 where
307 new_b = uniqAway in_scope bL
308
309 rnEtaR :: RnEnv2 -> Var -> (RnEnv2, Var)
310 -- ^ Similar to 'rnBndr2' but used for eta expansion
311 -- See Note [Eta expansion]
312 rnEtaR (RV2 { envL = envL, envR = envR, in_scope = in_scope }) bR
313 = (RV2 { envL = extendVarEnv envL new_b new_b -- Note [Eta expansion]
314 , envR = extendVarEnv envR bR new_b
315 , in_scope = extendInScopeSet in_scope new_b }, new_b)
316 where
317 new_b = uniqAway in_scope bR
318
319 delBndrL, delBndrR :: RnEnv2 -> Var -> RnEnv2
320 delBndrL rn@(RV2 { envL = env, in_scope = in_scope }) v
321 = rn { envL = env `delVarEnv` v, in_scope = in_scope `extendInScopeSet` v }
322 delBndrR rn@(RV2 { envR = env, in_scope = in_scope }) v
323 = rn { envR = env `delVarEnv` v, in_scope = in_scope `extendInScopeSet` v }
324
325 delBndrsL, delBndrsR :: RnEnv2 -> [Var] -> RnEnv2
326 delBndrsL rn@(RV2 { envL = env, in_scope = in_scope }) v
327 = rn { envL = env `delVarEnvList` v, in_scope = in_scope `extendInScopeSetList` v }
328 delBndrsR rn@(RV2 { envR = env, in_scope = in_scope }) v
329 = rn { envR = env `delVarEnvList` v, in_scope = in_scope `extendInScopeSetList` v }
330
331 rnOccL, rnOccR :: RnEnv2 -> Var -> Var
332 -- ^ Look up the renaming of an occurrence in the left or right term
333 rnOccL (RV2 { envL = env }) v = lookupVarEnv env v `orElse` v
334 rnOccR (RV2 { envR = env }) v = lookupVarEnv env v `orElse` v
335
336 rnOccL_maybe, rnOccR_maybe :: RnEnv2 -> Var -> Maybe Var
337 -- ^ Look up the renaming of an occurrence in the left or right term
338 rnOccL_maybe (RV2 { envL = env }) v = lookupVarEnv env v
339 rnOccR_maybe (RV2 { envR = env }) v = lookupVarEnv env v
340
341 inRnEnvL, inRnEnvR :: RnEnv2 -> Var -> Bool
342 -- ^ Tells whether a variable is locally bound
343 inRnEnvL (RV2 { envL = env }) v = v `elemVarEnv` env
344 inRnEnvR (RV2 { envR = env }) v = v `elemVarEnv` env
345
346 lookupRnInScope :: RnEnv2 -> Var -> Var
347 lookupRnInScope env v = lookupInScope (in_scope env) v `orElse` v
348
349 nukeRnEnvL, nukeRnEnvR :: RnEnv2 -> RnEnv2
350 -- ^ Wipe the left or right side renaming
351 nukeRnEnvL env = env { envL = emptyVarEnv }
352 nukeRnEnvR env = env { envR = emptyVarEnv }
353
354 rnSwap :: RnEnv2 -> RnEnv2
355 -- ^ swap the meaning of left and right
356 rnSwap (RV2 { envL = envL, envR = envR, in_scope = in_scope })
357 = RV2 { envL = envR, envR = envL, in_scope = in_scope }
358
359 {-
360 Note [Eta expansion]
361 ~~~~~~~~~~~~~~~~~~~~
362 When matching
363 (\x.M) ~ N
364 we rename x to x' with, where x' is not in scope in
365 either term. Then we want to behave as if we'd seen
366 (\x'.M) ~ (\x'.N x')
367 Since x' isn't in scope in N, the form (\x'. N x') doesn't
368 capture any variables in N. But we must nevertheless extend
369 the envR with a binding [x' -> x'], to support the occurs check.
370 For example, if we don't do this, we can get silly matches like
371 forall a. (\y.a) ~ v
372 succeeding with [a -> v y], which is bogus of course.
373
374
375 ************************************************************************
376 * *
377 Tidying
378 * *
379 ************************************************************************
380 -}
381
382 -- | When tidying up print names, we keep a mapping of in-scope occ-names
383 -- (the 'TidyOccEnv') and a Var-to-Var of the current renamings
384 type TidyEnv = (TidyOccEnv, VarEnv Var)
385
386 emptyTidyEnv :: TidyEnv
387 emptyTidyEnv = (emptyTidyOccEnv, emptyVarEnv)
388
389 {-
390 ************************************************************************
391 * *
392 \subsection{@VarEnv@s}
393 * *
394 ************************************************************************
395 -}
396
397 type VarEnv elt = UniqFM elt
398 type IdEnv elt = VarEnv elt
399 type TyVarEnv elt = VarEnv elt
400 type TyCoVarEnv elt = VarEnv elt
401 type CoVarEnv elt = VarEnv elt
402
403 emptyVarEnv :: VarEnv a
404 mkVarEnv :: [(Var, a)] -> VarEnv a
405 mkVarEnv_Directly :: [(Unique, a)] -> VarEnv a
406 zipVarEnv :: [Var] -> [a] -> VarEnv a
407 unitVarEnv :: Var -> a -> VarEnv a
408 alterVarEnv :: (Maybe a -> Maybe a) -> VarEnv a -> Var -> VarEnv a
409 extendVarEnv :: VarEnv a -> Var -> a -> VarEnv a
410 extendVarEnv_C :: (a->a->a) -> VarEnv a -> Var -> a -> VarEnv a
411 extendVarEnv_Acc :: (a->b->b) -> (a->b) -> VarEnv b -> Var -> a -> VarEnv b
412 extendVarEnv_Directly :: VarEnv a -> Unique -> a -> VarEnv a
413 plusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a
414 extendVarEnvList :: VarEnv a -> [(Var, a)] -> VarEnv a
415
416 lookupVarEnv_Directly :: VarEnv a -> Unique -> Maybe a
417 filterVarEnv_Directly :: (Unique -> a -> Bool) -> VarEnv a -> VarEnv a
418 delVarEnv_Directly :: VarEnv a -> Unique -> VarEnv a
419 partitionVarEnv :: (a -> Bool) -> VarEnv a -> (VarEnv a, VarEnv a)
420 restrictVarEnv :: VarEnv a -> VarSet -> VarEnv a
421 delVarEnvList :: VarEnv a -> [Var] -> VarEnv a
422 delVarEnv :: VarEnv a -> Var -> VarEnv a
423 minusVarEnv :: VarEnv a -> VarEnv b -> VarEnv a
424 intersectsVarEnv :: VarEnv a -> VarEnv a -> Bool
425 plusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a
426 plusVarEnv_CD :: (a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a
427 mapVarEnv :: (a -> b) -> VarEnv a -> VarEnv b
428 modifyVarEnv :: (a -> a) -> VarEnv a -> Var -> VarEnv a
429 varEnvElts :: VarEnv a -> [a]
430 varEnvKeys :: VarEnv a -> [Unique]
431 varEnvToList :: VarEnv a -> [(Unique, a)]
432
433 isEmptyVarEnv :: VarEnv a -> Bool
434 lookupVarEnv :: VarEnv a -> Var -> Maybe a
435 filterVarEnv :: (a -> Bool) -> VarEnv a -> VarEnv a
436 lookupVarEnv_NF :: VarEnv a -> Var -> a
437 lookupWithDefaultVarEnv :: VarEnv a -> a -> Var -> a
438 elemVarEnv :: Var -> VarEnv a -> Bool
439 elemVarEnvByKey :: Unique -> VarEnv a -> Bool
440 foldVarEnv :: (a -> b -> b) -> b -> VarEnv a -> b
441 foldVarEnv_Directly :: (Unique -> a -> b -> b) -> b -> VarEnv a -> b
442
443 elemVarEnv = elemUFM
444 elemVarEnvByKey = elemUFM_Directly
445 alterVarEnv = alterUFM
446 extendVarEnv = addToUFM
447 extendVarEnv_C = addToUFM_C
448 extendVarEnv_Acc = addToUFM_Acc
449 extendVarEnv_Directly = addToUFM_Directly
450 extendVarEnvList = addListToUFM
451 plusVarEnv_C = plusUFM_C
452 plusVarEnv_CD = plusUFM_CD
453 delVarEnvList = delListFromUFM
454 delVarEnv = delFromUFM
455 minusVarEnv = minusUFM
456 intersectsVarEnv e1 e2 = not (isEmptyVarEnv (e1 `intersectUFM` e2))
457 plusVarEnv = plusUFM
458 lookupVarEnv = lookupUFM
459 filterVarEnv = filterUFM
460 lookupWithDefaultVarEnv = lookupWithDefaultUFM
461 mapVarEnv = mapUFM
462 mkVarEnv = listToUFM
463 mkVarEnv_Directly= listToUFM_Directly
464 emptyVarEnv = emptyUFM
465 varEnvElts = eltsUFM
466 varEnvKeys = keysUFM
467 varEnvToList = ufmToList
468 unitVarEnv = unitUFM
469 isEmptyVarEnv = isNullUFM
470 foldVarEnv = foldUFM
471 foldVarEnv_Directly = foldUFM_Directly
472 lookupVarEnv_Directly = lookupUFM_Directly
473 filterVarEnv_Directly = filterUFM_Directly
474 delVarEnv_Directly = delFromUFM_Directly
475 partitionVarEnv = partitionUFM
476
477 restrictVarEnv env vs = filterVarEnv_Directly keep env
478 where
479 keep u _ = u `elemVarSetByKey` vs
480
481 zipVarEnv tyvars tys = mkVarEnv (zipEqual "zipVarEnv" tyvars tys)
482 lookupVarEnv_NF env id = case lookupVarEnv env id of
483 Just xx -> xx
484 Nothing -> panic "lookupVarEnv_NF: Nothing"
485
486 {-
487 @modifyVarEnv@: Look up a thing in the VarEnv,
488 then mash it with the modify function, and put it back.
489 -}
490
491 modifyVarEnv mangle_fn env key
492 = case (lookupVarEnv env key) of
493 Nothing -> env
494 Just xx -> extendVarEnv env key (mangle_fn xx)
495
496 modifyVarEnv_Directly :: (a -> a) -> UniqFM a -> Unique -> UniqFM a
497 modifyVarEnv_Directly mangle_fn env key
498 = case (lookupUFM_Directly env key) of
499 Nothing -> env
500 Just xx -> addToUFM_Directly env key (mangle_fn xx)
501
502 -- Deterministic VarEnv
503 -- See Note [Deterministic UniqFM] in UniqDFM for explanation why we need
504 -- DVarEnv.
505
506 type DVarEnv elt = UniqDFM elt
507
508 emptyDVarEnv :: DVarEnv a
509 emptyDVarEnv = emptyUDFM
510
511 extendDVarEnv :: DVarEnv a -> Var -> a -> DVarEnv a
512 extendDVarEnv = addToUDFM
513
514 lookupDVarEnv :: DVarEnv a -> Var -> Maybe a
515 lookupDVarEnv = lookupUDFM
516
517 foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b
518 foldDVarEnv = foldUDFM
519
520 mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b
521 mapDVarEnv = mapUDFM
522
523 alterDVarEnv :: (Maybe a -> Maybe a) -> DVarEnv a -> Var -> DVarEnv a
524 alterDVarEnv = alterUDFM