2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[DsMonad]{@DsMonad@: monadery used in desugaring}
7 #include "HsVersions.h"
11 initDs, returnDs, thenDs, andDs, mapDs, listDs,
12 mapAndUnzipDs, zipWithDs,
14 newTyVarsDs, cloneTyVarsDs,
15 duplicateLocalDs, newSysLocalDs, newSysLocalsDs,
17 getSrcLocDs, putSrcLocDs,
19 extendEnvDs, lookupEnvDs,
24 DsMatchContext(..), DsMatchKind(..), pprDsWarnings
30 import Bag ( emptyBag, snocBag, bagToList, Bag )
31 import BasicTypes ( SYN_IE(Module) )
32 import CmdLineOpts ( opt_PprUserLength )
33 import CoreSyn ( SYN_IE(CoreExpr) )
34 import CoreUtils ( substCoreExpr )
35 import ErrUtils ( SYN_IE(Warning) )
36 import HsSyn ( OutPat )
37 import Id ( mkSysLocal, mkIdWithNewUniq,
38 lookupIdEnv, growIdEnvList, GenId, SYN_IE(IdEnv),
41 import PprType ( GenType, GenTyVar )
42 import Outputable ( pprQuote, Outputable(..), PprStyle(..) )
44 import SrcLoc ( noSrcLoc, SrcLoc )
45 import TcHsSyn ( SYN_IE(TypecheckedPat) )
46 import Type ( SYN_IE(Type) )
47 import TyVar ( nullTyVarEnv, cloneTyVar, GenTyVar{-instance Eq-}, SYN_IE(TyVar) )
48 import Unique ( Unique{-instances-} )
49 import UniqSupply ( splitUniqSupply, getUnique, getUniques,
50 mapUs, thenUs, returnUs, SYN_IE(UniqSM),
52 import Util ( assoc, mapAccumL, zipWithEqual, panic )
57 Now the mondo monad magic (yes, @DsM@ is a silly name)---carry around
58 a @UniqueSupply@ and some annotations, which
59 presumably include source-file location information:
63 -> SrcLoc -- to put in pattern-matching error msgs
64 -> (Module, Group) -- module + group name : for SCC profiling
67 -> (result, DsWarnings)
69 type DsWarnings = Bag Warning -- The desugarer reports matches which are
70 -- completely shadowed or incomplete patterns
72 type Group = FAST_STRING
76 {-# INLINE returnDs #-}
78 -- initDs returns the UniqSupply out the end (not just the result)
82 -> (Module, Group) -- module name: for profiling; (group name: from switches)
86 initDs init_us env module_and_group action
87 = action init_us noSrcLoc module_and_group env emptyBag
89 thenDs :: DsM a -> (a -> DsM b) -> DsM b
90 andDs :: (a -> a -> a) -> DsM a -> DsM a -> DsM a
92 thenDs m1 m2 us loc mod_and_grp env warns
93 = case splitUniqSupply us of { (s1, s2) ->
94 case (m1 s1 loc mod_and_grp env warns) of { (result, warns1) ->
95 m2 result s2 loc mod_and_grp env warns1}}
97 andDs combiner m1 m2 us loc mod_and_grp env warns
98 = case splitUniqSupply us of { (s1, s2) ->
99 case (m1 s1 loc mod_and_grp env warns) of { (result1, warns1) ->
100 case (m2 s2 loc mod_and_grp env warns1) of { (result2, warns2) ->
101 (combiner result1 result2, warns2) }}}
103 returnDs :: a -> DsM a
104 returnDs result us loc mod_and_grp env warns = (result, warns)
106 listDs :: [DsM a] -> DsM [a]
107 listDs [] = returnDs []
110 listDs xs `thenDs` \ rs ->
113 mapDs :: (a -> DsM b) -> [a] -> DsM [b]
115 mapDs f [] = returnDs []
117 = f x `thenDs` \ r ->
118 mapDs f xs `thenDs` \ rs ->
121 mapAndUnzipDs :: (a -> DsM (b, c)) -> [a] -> DsM ([b], [c])
123 mapAndUnzipDs f [] = returnDs ([], [])
124 mapAndUnzipDs f (x:xs)
125 = f x `thenDs` \ (r1, r2) ->
126 mapAndUnzipDs f xs `thenDs` \ (rs1, rs2) ->
127 returnDs (r1:rs1, r2:rs2)
129 zipWithDs :: (a -> b -> DsM c) -> [a] -> [b] -> DsM [c]
131 zipWithDs f [] ys = returnDs []
132 zipWithDs f (x:xs) (y:ys)
133 = f x y `thenDs` \ r ->
134 zipWithDs f xs ys `thenDs` \ rs ->
138 And all this mysterious stuff is so we can occasionally reach out and
139 grab one or more names. @newLocalDs@ isn't exported---exported
140 functions are defined with it. The difference in name-strings makes
141 it easier to read debugging output.
144 newLocalDs :: FAST_STRING -> Type -> DsM Id
145 newLocalDs nm ty us loc mod_and_grp env warns
146 = case (getUnique us) of { assigned_uniq ->
147 (mkSysLocal nm assigned_uniq ty loc, warns) }
149 newSysLocalDs = newLocalDs SLIT("ds")
150 newSysLocalsDs tys = mapDs (newLocalDs SLIT("ds")) tys
151 newFailLocalDs = newLocalDs SLIT("fail")
153 duplicateLocalDs :: Id -> DsM Id
154 duplicateLocalDs old_local us loc mod_and_grp env warns
155 = case (getUnique us) of { assigned_uniq ->
156 (mkIdWithNewUniq old_local assigned_uniq, warns) }
158 cloneTyVarsDs :: [TyVar] -> DsM [TyVar]
159 cloneTyVarsDs tyvars us loc mod_and_grp env warns
160 = case (getUniques (length tyvars) us) of { uniqs ->
161 (zipWithEqual "cloneTyVarsDs" cloneTyVar tyvars uniqs, warns) }
165 newTyVarsDs :: [TyVar] -> DsM [TyVar]
167 newTyVarsDs tyvar_tmpls us loc mod_and_grp env warns
168 = case (getUniques (length tyvar_tmpls) us) of { uniqs ->
169 (zipWithEqual "newTyVarsDs" cloneTyVar tyvar_tmpls uniqs, warns) }
172 We can also reach out and either set/grab location information from
173 the @SrcLoc@ being carried around.
175 uniqSMtoDsM :: UniqSM a -> DsM a
177 uniqSMtoDsM u_action us loc mod_and_grp env warns
178 = (u_action us, warns)
180 getSrcLocDs :: DsM SrcLoc
181 getSrcLocDs us loc mod_and_grp env warns
184 putSrcLocDs :: SrcLoc -> DsM a -> DsM a
185 putSrcLocDs new_loc expr us old_loc mod_and_grp env warns
186 = expr us new_loc mod_and_grp env warns
188 dsWarn :: Warning -> DsM ()
189 dsWarn warn us loc mod_and_grp env warns = ((), warns `snocBag` warn)
194 getModuleAndGroupDs :: DsM (FAST_STRING, FAST_STRING)
195 getModuleAndGroupDs us loc mod_and_grp env warns
196 = (mod_and_grp, warns)
200 type DsIdEnv = IdEnv Id
202 extendEnvDs :: [(Id, Id)] -> DsM a -> DsM a
204 extendEnvDs pairs then_do us loc mod_and_grp old_env warns
205 = then_do us loc mod_and_grp (growIdEnvList old_env pairs) warns
207 lookupEnvDs :: Id -> DsM Id
208 lookupEnvDs id us loc mod_and_grp env warns
209 = (case (lookupIdEnv env id) of
215 %************************************************************************
217 %* type synonym EquationInfo and access functions for its pieces *
219 %************************************************************************
223 = DsMatchContext DsMatchKind [TypecheckedPat] SrcLoc
237 pprDsWarnings :: PprStyle -> DsWarnings -> Doc
238 pprDsWarnings sty warns = vcat [ warn sty | warn <- (bagToList warns)]