2 % (c) The GRASP/AQUA Project, Glasgow University, 1998
4 \section[DataCon]{@DataCon@: Data Constructors}
11 dataConType, dataConSig, dataConName, dataConTag,
12 dataConOrigArgTys, dataConArgTys, dataConRawArgTys, dataConTyCon,
13 dataConFieldLabels, dataConStrictMarks, dataConSourceArity,
14 dataConNumFields, dataConNumInstArgs, dataConId,
15 isNullaryDataCon, isTupleCon, isUnboxedTupleCon,
19 #include "HsVersions.h"
21 import CmdLineOpts ( opt_DictsStrict )
23 import Type ( Type, ThetaType, TauType,
24 mkSigmaTy, mkFunTys, mkTyConApp,
25 mkTyVarTys, mkDictTy, substTy,
26 splitAlgTyConApp_maybe
29 import TyCon ( TyCon, tyConDataCons, isDataTyCon,
30 isTupleTyCon, isUnboxedTupleTyCon )
31 import Class ( classTyCon )
32 import Name ( Name, NamedThing(..), nameUnique, isLocallyDefinedName )
33 import Var ( TyVar, Id )
35 import FieldLabel ( FieldLabel )
36 import BasicTypes ( StrictnessMark(..), Arity )
38 import Unique ( Unique, Uniquable(..) )
39 import CmdLineOpts ( opt_UnboxStrictFields )
46 %************************************************************************
48 \subsection{Data constructors}
50 %************************************************************************
54 = MkData { -- Used for data constructors only;
55 -- there *is* no constructor for a newtype
57 dcUnique :: Unique, -- Cached from Name
62 -- data Eq a => T a = forall b. Ord b => MkT a [b]
64 dcType :: Type, -- Type of the constructor
65 -- forall ab . Ord b => a -> [b] -> MkT a
66 -- (this is *not* of the constructor Id:
67 -- see notes after this data type declaration)
69 -- The next six fields express the type of the constructor, in pieces
75 -- dcExTheta = [Ord b]
76 -- dcOrigArgTys = [a,List b]
79 dcTyVars :: [TyVar], -- Type vars and context for the data type decl
82 dcExTyVars :: [TyVar], -- Ditto for the context of the constructor,
83 dcExTheta :: ThetaType, -- the existentially quantified stuff
85 dcOrigArgTys :: [Type], -- Original argument types
86 -- (before unboxing and flattening of
88 dcRepArgTys :: [Type], -- Constructor Argument types
89 dcTyCon :: TyCon, -- Result tycon
91 -- Now the strictness annotations and field labels of the constructor
92 dcUserStricts :: [StrictnessMark],
93 -- Strictness annotations, as placed on the data type defn,
94 -- in the same order as the argument types;
95 -- length = dataConNumFields dataCon
97 dcRealStricts :: [StrictnessMark],
98 -- Strictness annotations as deduced by the compiler. May
99 -- include some MarkedUnboxed fields that are MarkedStrict
101 -- length = dataConNumFields dataCon
103 dcFields :: [FieldLabel],
104 -- Field labels for this constructor, in the
105 -- same order as the argument types;
106 -- length = 0 (if not a record) or dataConSourceArity.
108 -- Finally, the curried function that corresponds to the constructor
109 -- mkT :: forall a b. (Eq a, Ord b) => a -> [b] -> T a
110 -- mkT = /\ab. \deq dord p qs. Con MkT [a, b, dord, p, qs]
111 -- This unfolding is built in MkId.mkDataConId
113 dcId :: Id -- The corresponding Id
119 fIRST_TAG = 1 -- Tags allocated from here for real constructors
122 The dcType field contains the type of the representation of a contructor
123 This may differ from the type of the contructor *Id* (built
124 by MkId.mkDataConId) for two reasons:
125 a) the constructor Id may be overloaded, but the dictionary isn't stored
126 e.g. data Eq a => T a = MkT a a
128 b) the constructor may store an unboxed version of a strict field.
130 Here's an example illustrating both:
131 data Ord a => T a = MkT Int! a
133 T :: Ord a => Int -> a -> T a
135 Trep :: Int# -> a -> T a
136 Actually, the unboxed part isn't implemented yet!
140 instance Eq DataCon where
141 a == b = getUnique a == getUnique b
142 a /= b = getUnique a /= getUnique b
144 instance Ord DataCon where
145 a <= b = getUnique a <= getUnique b
146 a < b = getUnique a < getUnique b
147 a >= b = getUnique a >= getUnique b
148 a > b = getUnique a > getUnique b
149 compare a b = getUnique a `compare` getUnique b
151 instance Uniquable DataCon where
154 instance NamedThing DataCon where
157 instance Outputable DataCon where
158 ppr con = ppr (dataConName con)
160 instance Show DataCon where
161 showsPrec p con = showsPrecSDoc p (ppr con)
166 -> [StrictnessMark] -> [FieldLabel]
167 -> [TyVar] -> ThetaType
168 -> [TyVar] -> ThetaType
169 -> [TauType] -> TyCon
172 -- Can get the tag from the TyCon
174 mkDataCon name arg_stricts fields tyvars theta ex_tyvars ex_theta orig_arg_tys tycon id
175 = ASSERT(length arg_stricts == length orig_arg_tys)
176 -- The 'stricts' passed to mkDataCon are simply those for the
177 -- source-language arguments. We add extra ones for the
178 -- dictionary arguments right here.
181 con = MkData {dcName = name, dcUnique = nameUnique name,
182 dcTyVars = tyvars, dcTheta = theta,
183 dcOrigArgTys = orig_arg_tys,
184 dcRepArgTys = rep_arg_tys,
185 dcExTyVars = ex_tyvars, dcExTheta = ex_theta,
186 dcRealStricts = all_stricts, dcUserStricts = user_stricts,
187 dcFields = fields, dcTag = tag, dcTyCon = tycon, dcType = ty,
190 (real_arg_stricts, strict_arg_tyss)
191 = unzip (zipWith (unbox_strict_arg_ty tycon) arg_stricts orig_arg_tys)
192 rep_arg_tys = concat strict_arg_tyss
194 all_stricts = (map mk_dict_strict_mark ex_theta) ++ real_arg_stricts
195 user_stricts = (map mk_dict_strict_mark ex_theta) ++ arg_stricts
196 -- Add a strictness flag for the existential dictionary arguments
198 tag = assoc "mkDataCon" (tyConDataCons tycon `zip` [fIRST_TAG..]) con
199 ty = mkSigmaTy (tyvars ++ ex_tyvars)
201 (mkFunTys rep_arg_tys
202 (mkTyConApp tycon (mkTyVarTys tyvars)))
204 mk_dict_strict_mark (clas,tys)
206 -- Don't mark newtype things as strict!
207 isDataTyCon (classTyCon clas) = MarkedStrict
208 | otherwise = NotMarkedStrict
210 -- We attempt to unbox/unpack a strict field when either:
211 -- (i) The tycon is imported, and the field is marked '! !', or
212 -- (ii) The tycon is defined in this module, the field is marked '!',
213 -- and the -funbox-strict-fields flag is on.
215 -- This ensures that if we compile some modules with -funbox-strict-fields and
216 -- some without, the compiler doesn't get confused about the constructor
219 unbox_strict_arg_ty :: TyCon -> StrictnessMark -> Type -> (StrictnessMark, [Type])
220 unbox_strict_arg_ty tycon NotMarkedStrict ty
221 = (NotMarkedStrict, [ty])
222 unbox_strict_arg_ty tycon MarkedStrict ty
223 | not opt_UnboxStrictFields
224 || not (isLocallyDefinedName (getName tycon)) = (MarkedStrict, [ty])
225 unbox_strict_arg_ty tycon marked_unboxed ty
226 -- MarkedUnboxed || (MarkedStrict && opt_UnboxStrictFields && not imported)
227 = case splitAlgTyConApp_maybe ty of
229 -> panic (showSDoc (hcat [
230 text "unbox_strict_arg_ty: constructors for ",
232 text " not available."
234 Just (tycon,ty_args,[con])
235 -> case maybe_unpack_fields emptyUniqSet
236 (zip (dataConOrigArgTys con ty_args)
239 Nothing -> (MarkedStrict, [ty])
240 Just tys -> (MarkedUnboxed con tys, tys)
241 _ -> (MarkedStrict, [ty])
243 -- bail out if we encounter the same tycon twice. This avoids problems like
248 -- where no useful unpacking can be done.
250 maybe_unpack_field :: UniqSet TyCon -> Type -> StrictnessMark -> Maybe [Type]
251 maybe_unpack_field set ty NotMarkedStrict
253 maybe_unpack_field set ty MarkedStrict | not opt_UnboxStrictFields
255 maybe_unpack_field set ty strict
256 = case splitAlgTyConApp_maybe ty of
257 Just (tycon,ty_args,[con])
258 | tycon `elementOfUniqSet` set -> Nothing
260 let set' = addOneToUniqSet set tycon in
261 maybe_unpack_fields set'
262 (zip (dataConOrigArgTys con ty_args)
266 maybe_unpack_fields :: UniqSet TyCon -> [(Type,StrictnessMark)] -> Maybe [Type]
267 maybe_unpack_fields set tys
268 | any isNothing unpacked_fields = Nothing
269 | otherwise = Just (concat (catMaybes unpacked_fields))
270 where unpacked_fields = map (\(ty,str) -> maybe_unpack_field set ty str) tys
275 dataConName :: DataCon -> Name
278 dataConTag :: DataCon -> ConTag
281 dataConTyCon :: DataCon -> TyCon
282 dataConTyCon = dcTyCon
284 dataConType :: DataCon -> Type
287 dataConId :: DataCon -> Id
291 dataConFieldLabels :: DataCon -> [FieldLabel]
292 dataConFieldLabels = dcFields
294 dataConStrictMarks :: DataCon -> [StrictnessMark]
295 dataConStrictMarks = dcRealStricts
297 dataConRawArgTys :: DataCon -> [TauType] -- a function of convenience
298 dataConRawArgTys = dcRepArgTys
300 dataConSourceArity :: DataCon -> Arity
301 -- Source-level arity of the data constructor
302 dataConSourceArity dc = length (dcOrigArgTys dc)
304 dataConSig :: DataCon -> ([TyVar], ThetaType,
308 dataConSig (MkData {dcTyVars = tyvars, dcTheta = theta,
309 dcExTyVars = ex_tyvars, dcExTheta = ex_theta,
310 dcOrigArgTys = arg_tys, dcTyCon = tycon})
311 = (tyvars, theta, ex_tyvars, ex_theta, arg_tys, tycon)
313 dataConArgTys, dataConOrigArgTys :: DataCon
314 -> [Type] -- Instantiated at these types
315 -- NB: these INCLUDE the existentially quantified arg types
316 -> [Type] -- Needs arguments of these types
317 -- NB: these INCLUDE the existentially quantified dict args
318 -- but EXCLUDE the data-decl context which is discarded
320 dataConArgTys (MkData {dcRepArgTys = arg_tys, dcTyVars = tyvars,
321 dcExTyVars = ex_tyvars, dcExTheta = ex_theta}) inst_tys
322 = map (substTy (zipVarEnv (tyvars ++ ex_tyvars) inst_tys))
323 ([mkDictTy cls tys | (cls,tys) <- ex_theta] ++ arg_tys)
325 dataConOrigArgTys (MkData {dcOrigArgTys = arg_tys, dcTyVars = tyvars,
326 dcExTyVars = ex_tyvars, dcExTheta = ex_theta}) inst_tys
327 = map (substTy (zipVarEnv (tyvars ++ ex_tyvars) inst_tys))
328 ([mkDictTy cls tys | (cls,tys) <- ex_theta] ++ arg_tys)
331 dataConNumFields gives the number of actual fields in the
332 {\em representation} of the data constructor. This may be more than appear
333 in the source code; the extra ones are the existentially quantified
337 -- Number of type-instantiation arguments
338 -- All the remaining arguments of the DataCon are (notionally)
339 -- stored in the DataCon, and are matched in a case expression
340 dataConNumInstArgs (MkData {dcTyVars = tyvars}) = length tyvars
342 dataConNumFields (MkData {dcExTheta = theta, dcRepArgTys = arg_tys})
343 = length theta + length arg_tys
346 = dataConNumFields con == 0 -- function of convenience
348 isTupleCon :: DataCon -> Bool
349 isTupleCon (MkData {dcTyCon = tc}) = isTupleTyCon tc
351 isUnboxedTupleCon :: DataCon -> Bool
352 isUnboxedTupleCon (MkData {dcTyCon = tc}) = isUnboxedTupleTyCon tc
354 isExistentialDataCon :: DataCon -> Bool
355 isExistentialDataCon (MkData {dcExTyVars = tvs}) = not (null tvs)