2 % (c) The GRASP Project, Glasgow University, 1994-1998
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
6 This module is about types that can be defined in Haskell, but which
7 must be wired into the compiler nonetheless.
9 This module tracks the ``state interface'' document, ``GHC prelude:
10 types and operations.''
16 boolTy, boolTyCon, boolTyCon_RDR, boolTyConName,
17 trueDataCon, trueDataConId, true_RDR,
18 falseDataCon, falseDataConId, false_RDR,
20 charTyCon, charDataCon, charTyCon_RDR,
21 charTy, stringTy, charTyConName,
24 doubleTyCon, doubleDataCon, doubleTy, doubleTyConName,
26 floatTyCon, floatDataCon, floatTy, floatTyConName,
28 intTyCon, intDataCon, intTyCon_RDR, intDataCon_RDR, intTyConName,
31 listTyCon, nilDataCon, consDataCon,
32 listTyCon_RDR, consDataCon_RDR, listTyConName,
38 unitTyCon, unitDataCon, unitDataConId, pairTyCon,
39 unboxedSingletonTyCon, unboxedSingletonDataCon,
40 unboxedPairTyCon, unboxedPairDataCon,
42 boxedTupleArr, unboxedTupleArr,
48 parrTyCon, parrFakeCon, isPArrTyCon, isPArrFakeCon,
49 parrTyCon_RDR, parrTyConName
52 import {-# SOURCE #-} MkId( mkDataConIds )
59 import Constants ( mAX_TUPLE_SIZE )
60 import Module ( Module )
62 import Name ( Name, BuiltInSyntax(..), nameUnique, nameOccName,
63 nameModule, mkWiredInName )
64 import OccName ( mkOccNameFS, tcName, dataName, mkTupleOcc,
66 import DataCon ( DataCon, mkDataCon, dataConWorkId, dataConSourceArity )
68 import TyCon ( TyCon, AlgTyConRhs(DataTyCon), tyConDataCons,
69 mkTupleTyCon, mkAlgTyCon, tyConName,
70 TyConParent(NoParentTyCon) )
72 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed,
75 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTy, mkTyVarTys,
77 import Coercion ( unsafeCoercionTyCon, symCoercionTyCon,
78 transCoercionTyCon, leftCoercionTyCon,
79 rightCoercionTyCon, instCoercionTyCon )
80 import TypeRep ( mkArrowKinds, liftedTypeKind, ubxTupleKind )
81 import Unique ( incrUnique, mkTupleTyConUnique,
82 mkTupleDataConUnique, mkPArrDataConUnique )
87 alpha_tyvar :: [TyVar]
88 alpha_tyvar = [alphaTyVar]
95 %************************************************************************
97 \subsection{Wired in type constructors}
99 %************************************************************************
101 If you change which things are wired in, make sure you change their
102 names in PrelNames, so they use wTcQual, wDataQual, etc
105 wiredInTyCons :: [TyCon] -- Excludes tuples
106 -- This list is used only to define PrelInfo.wiredInThings
108 -- It does not need to include kind constructors, because
109 -- all that wiredInThings does is to initialise the Name table,
110 -- and kind constructors don't appear in source code.
112 wiredInTyCons = [ unitTyCon -- Not treated like other tuples, because
113 -- it's defined in GHC.Base, and there's only
114 -- one of it. We put it in wiredInTyCons so
115 -- that it'll pre-populate the name cache, so
116 -- the special case in lookupOrigNameCache
117 -- doesn't need to look out for it
125 , unsafeCoercionTyCon
135 mkWiredInTyConName :: BuiltInSyntax -> Module -> FastString -> Unique -> TyCon -> Name
136 mkWiredInTyConName built_in modu fs unique tycon
137 = mkWiredInName modu (mkOccNameFS tcName fs) unique
138 (ATyCon tycon) -- Relevant TyCon
141 mkWiredInDataConName :: BuiltInSyntax -> Module -> FastString -> Unique -> DataCon -> Name
142 mkWiredInDataConName built_in modu fs unique datacon
143 = mkWiredInName modu (mkOccNameFS dataName fs) unique
144 (ADataCon datacon) -- Relevant DataCon
147 charTyConName, charDataConName, intTyConName, intDataConName :: Name
148 charTyConName = mkWiredInTyConName UserSyntax gHC_BASE (fsLit "Char") charTyConKey charTyCon
149 charDataConName = mkWiredInDataConName UserSyntax gHC_BASE (fsLit "C#") charDataConKey charDataCon
150 intTyConName = mkWiredInTyConName UserSyntax gHC_BASE (fsLit "Int") intTyConKey intTyCon
151 intDataConName = mkWiredInDataConName UserSyntax gHC_BASE (fsLit "I#") intDataConKey intDataCon
153 boolTyConName, falseDataConName, trueDataConName :: Name
154 boolTyConName = mkWiredInTyConName UserSyntax gHC_BOOL (fsLit "Bool") boolTyConKey boolTyCon
155 falseDataConName = mkWiredInDataConName UserSyntax gHC_BOOL (fsLit "False") falseDataConKey falseDataCon
156 trueDataConName = mkWiredInDataConName UserSyntax gHC_BOOL (fsLit "True") trueDataConKey trueDataCon
158 listTyConName, nilDataConName, consDataConName :: Name
159 listTyConName = mkWiredInTyConName BuiltInSyntax gHC_BASE (fsLit "[]") listTyConKey listTyCon
160 nilDataConName = mkWiredInDataConName BuiltInSyntax gHC_BASE (fsLit "[]") nilDataConKey nilDataCon
161 consDataConName = mkWiredInDataConName BuiltInSyntax gHC_BASE (fsLit ":") consDataConKey consDataCon
163 floatTyConName, floatDataConName, doubleTyConName, doubleDataConName :: Name
164 floatTyConName = mkWiredInTyConName UserSyntax gHC_FLOAT (fsLit "Float") floatTyConKey floatTyCon
165 floatDataConName = mkWiredInDataConName UserSyntax gHC_FLOAT (fsLit "F#") floatDataConKey floatDataCon
166 doubleTyConName = mkWiredInTyConName UserSyntax gHC_FLOAT (fsLit "Double") doubleTyConKey doubleTyCon
167 doubleDataConName = mkWiredInDataConName UserSyntax gHC_FLOAT (fsLit "D#") doubleDataConKey doubleDataCon
169 parrTyConName, parrDataConName :: Name
170 parrTyConName = mkWiredInTyConName BuiltInSyntax gHC_PARR (fsLit "[::]") parrTyConKey parrTyCon
171 parrDataConName = mkWiredInDataConName UserSyntax gHC_PARR (fsLit "PArr") parrDataConKey parrDataCon
173 boolTyCon_RDR, false_RDR, true_RDR, intTyCon_RDR, charTyCon_RDR,
174 intDataCon_RDR, listTyCon_RDR, consDataCon_RDR, parrTyCon_RDR:: RdrName
175 boolTyCon_RDR = nameRdrName boolTyConName
176 false_RDR = nameRdrName falseDataConName
177 true_RDR = nameRdrName trueDataConName
178 intTyCon_RDR = nameRdrName intTyConName
179 charTyCon_RDR = nameRdrName charTyConName
180 intDataCon_RDR = nameRdrName intDataConName
181 listTyCon_RDR = nameRdrName listTyConName
182 consDataCon_RDR = nameRdrName consDataConName
183 parrTyCon_RDR = nameRdrName parrTyConName
185 tySuperKindTyCon_RDR = nameRdrName tySuperKindTyConName
186 coSuperKindTyCon_RDR = nameRdrName coSuperKindTyConName
187 liftedTypeKindTyCon_RDR = nameRdrName liftedTypeKindTyConName
188 openTypeKindTyCon_RDR = nameRdrName openTypeKindTyConName
189 unliftedTypeKindTyCon_RDR = nameRdrName unliftedTypeKindTyConName
190 ubxTupleKindTyCon_RDR = nameRdrName ubxTupleKindTyConName
191 argTypeKindTyCon_RDR = nameRdrName argTypeKindTyConName
192 funKindTyCon_RDR = nameRdrName funKindTyConName
197 %************************************************************************
199 \subsection{mkWiredInTyCon}
201 %************************************************************************
204 pcNonRecDataTyCon :: Name -> [TyVar] -> [DataCon] -> TyCon
205 pcNonRecDataTyCon = pcTyCon False NonRecursive
206 pcRecDataTyCon :: Name -> [TyVar] -> [DataCon] -> TyCon
207 pcRecDataTyCon = pcTyCon False Recursive
209 pcTyCon :: Bool -> RecFlag -> Name -> [TyVar] -> [DataCon] -> TyCon
210 pcTyCon is_enum is_rec name tyvars cons
213 tycon = mkAlgTyCon name
214 (mkArrowKinds (map tyVarKind tyvars) liftedTypeKind)
216 [] -- No stupid theta
217 (DataTyCon cons is_enum)
218 [] -- No record selectors
221 True -- All the wired-in tycons have generics
222 False -- Not in GADT syntax
224 pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon
225 pcDataCon = pcDataConWithFixity False
227 pcDataConWithFixity :: Bool -> Name -> [TyVar] -> [Type] -> TyCon -> DataCon
228 -- The Name should be in the DataName name space; it's the name
229 -- of the DataCon itself.
231 -- The unique is the first of two free uniques;
232 -- the first is used for the datacon itself,
233 -- the second is used for the "worker name"
235 pcDataConWithFixity declared_infix dc_name tyvars arg_tys tycon
238 data_con = mkDataCon dc_name declared_infix
239 (map (const NotMarkedStrict) arg_tys)
240 [] -- No labelled fields
242 [] -- No existential type variables
243 [] -- No equality spec
246 [] -- No stupid theta
247 (mkDataConIds bogus_wrap_name wrk_name data_con)
250 modu = nameModule dc_name
251 wrk_occ = mkDataConWorkerOcc (nameOccName dc_name)
252 wrk_key = incrUnique (nameUnique dc_name)
253 wrk_name = mkWiredInName modu wrk_occ wrk_key
254 (AnId (dataConWorkId data_con)) UserSyntax
255 bogus_wrap_name = pprPanic "Wired-in data wrapper id" (ppr dc_name)
256 -- Wired-in types are too simple to need wrappers
260 %************************************************************************
262 \subsection[TysWiredIn-tuples]{The tuple types}
264 %************************************************************************
267 tupleTyCon :: Boxity -> Arity -> TyCon
268 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
269 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
270 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
272 tupleCon :: Boxity -> Arity -> DataCon
273 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
274 tupleCon Boxed i = snd (boxedTupleArr ! i)
275 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
277 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
278 boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]]
279 unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]]
281 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
282 mk_tuple boxity arity = (tycon, tuple_con)
284 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
285 modu = mkTupleModule boxity arity
286 tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
287 (ATyCon tycon) BuiltInSyntax
288 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
289 res_kind | isBoxed boxity = liftedTypeKind
290 | otherwise = ubxTupleKind
292 tyvars | isBoxed boxity = take arity alphaTyVars
293 | otherwise = take arity openAlphaTyVars
295 tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
296 tyvar_tys = mkTyVarTys tyvars
297 dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
298 (ADataCon tuple_con) BuiltInSyntax
299 tc_uniq = mkTupleTyConUnique boxity arity
300 dc_uniq = mkTupleDataConUnique boxity arity
301 gen_info = True -- Tuples all have generics..
302 -- hmm: that's a *lot* of code
305 unitTyCon = tupleTyCon Boxed 0
306 unitDataCon :: DataCon
307 unitDataCon = head (tyConDataCons unitTyCon)
309 unitDataConId = dataConWorkId unitDataCon
312 pairTyCon = tupleTyCon Boxed 2
314 unboxedSingletonTyCon :: TyCon
315 unboxedSingletonTyCon = tupleTyCon Unboxed 1
316 unboxedSingletonDataCon :: DataCon
317 unboxedSingletonDataCon = tupleCon Unboxed 1
319 unboxedPairTyCon :: TyCon
320 unboxedPairTyCon = tupleTyCon Unboxed 2
321 unboxedPairDataCon :: DataCon
322 unboxedPairDataCon = tupleCon Unboxed 2
325 %************************************************************************
327 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
329 %************************************************************************
333 charTy = mkTyConTy charTyCon
336 charTyCon = pcNonRecDataTyCon charTyConName [] [charDataCon]
337 charDataCon :: DataCon
338 charDataCon = pcDataCon charDataConName [] [charPrimTy] charTyCon
341 stringTy = mkListTy charTy -- convenience only
346 intTy = mkTyConTy intTyCon
349 intTyCon = pcNonRecDataTyCon intTyConName [] [intDataCon]
350 intDataCon :: DataCon
351 intDataCon = pcDataCon intDataConName [] [intPrimTy] intTyCon
356 floatTy = mkTyConTy floatTyCon
359 floatTyCon = pcNonRecDataTyCon floatTyConName [] [floatDataCon]
360 floatDataCon :: DataCon
361 floatDataCon = pcDataCon floatDataConName [] [floatPrimTy] floatTyCon
366 doubleTy = mkTyConTy doubleTyCon
369 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [doubleDataCon]
371 doubleDataCon :: DataCon
372 doubleDataCon = pcDataCon doubleDataConName [] [doublePrimTy] doubleTyCon
376 %************************************************************************
378 \subsection[TysWiredIn-Bool]{The @Bool@ type}
380 %************************************************************************
382 An ordinary enumeration type, but deeply wired in. There are no
383 magical operations on @Bool@ (just the regular Prelude code).
385 {\em BEGIN IDLE SPECULATION BY SIMON}
387 This is not the only way to encode @Bool@. A more obvious coding makes
388 @Bool@ just a boxed up version of @Bool#@, like this:
391 data Bool = MkBool Bool#
394 Unfortunately, this doesn't correspond to what the Report says @Bool@
395 looks like! Furthermore, we get slightly less efficient code (I
396 think) with this coding. @gtInt@ would look like this:
399 gtInt :: Int -> Int -> Bool
400 gtInt x y = case x of I# x# ->
402 case (gtIntPrim x# y#) of
406 Notice that the result of the @gtIntPrim@ comparison has to be turned
407 into an integer (here called @b#@), and returned in a @MkBool@ box.
409 The @if@ expression would compile to this:
412 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
415 I think this code is a little less efficient than the previous code,
416 but I'm not certain. At all events, corresponding with the Report is
417 important. The interesting thing is that the language is expressive
418 enough to describe more than one alternative; and that a type doesn't
419 necessarily need to be a straightforwardly boxed version of its
420 primitive counterpart.
422 {\em END IDLE SPECULATION BY SIMON}
426 boolTy = mkTyConTy boolTyCon
429 boolTyCon = pcTyCon True NonRecursive boolTyConName
430 [] [falseDataCon, trueDataCon]
432 falseDataCon, trueDataCon :: DataCon
433 falseDataCon = pcDataCon falseDataConName [] [] boolTyCon
434 trueDataCon = pcDataCon trueDataConName [] [] boolTyCon
436 falseDataConId, trueDataConId :: Id
437 falseDataConId = dataConWorkId falseDataCon
438 trueDataConId = dataConWorkId trueDataCon
441 %************************************************************************
443 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
445 %************************************************************************
447 Special syntax, deeply wired in, but otherwise an ordinary algebraic
450 data [] a = [] | a : (List a)
452 data (,) a b = (,,) a b
457 mkListTy :: Type -> Type
458 mkListTy ty = mkTyConApp listTyCon [ty]
461 listTyCon = pcRecDataTyCon listTyConName alpha_tyvar [nilDataCon, consDataCon]
463 nilDataCon :: DataCon
464 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] listTyCon
465 consDataCon :: DataCon
466 consDataCon = pcDataConWithFixity True {- Declared infix -}
468 alpha_tyvar [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
469 -- Interesting: polymorphic recursion would help here.
470 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
471 -- gets the over-specific type (Type -> Type)
474 %************************************************************************
476 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
478 %************************************************************************
480 The tuple types are definitely magic, because they form an infinite
485 They have a special family of type constructors, of type @TyCon@
486 These contain the tycon arity, but don't require a Unique.
489 They have a special family of constructors, of type
490 @Id@. Again these contain their arity but don't need a Unique.
493 There should be a magic way of generating the info tables and
494 entry code for all tuples.
496 But at the moment we just compile a Haskell source
497 file\srcloc{lib/prelude/...} containing declarations like:
500 data Tuple2 a b = Tup2 a b
501 data Tuple3 a b c = Tup3 a b c
502 data Tuple4 a b c d = Tup4 a b c d
505 The print-names associated with the magic @Id@s for tuple constructors
506 ``just happen'' to be the same as those generated by these
510 The instance environment should have a magic way to know
511 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
512 so on. \ToDo{Not implemented yet.}
515 There should also be a way to generate the appropriate code for each
516 of these instances, but (like the info tables and entry code) it is
517 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
521 mkTupleTy :: Boxity -> Int -> [Type] -> Type
522 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
525 unitTy = mkTupleTy Boxed 0 []
528 %************************************************************************
530 \subsection[TysWiredIn-PArr]{The @[::]@ type}
532 %************************************************************************
534 Special syntax for parallel arrays needs some wired in definitions.
537 -- construct a type representing the application of the parallel array
540 mkPArrTy :: Type -> Type
541 mkPArrTy ty = mkTyConApp parrTyCon [ty]
543 -- represents the type constructor of parallel arrays
545 -- * this must match the definition in `PrelPArr'
547 -- NB: Although the constructor is given here, it will not be accessible in
548 -- user code as it is not in the environment of any compiled module except
552 parrTyCon = pcNonRecDataTyCon parrTyConName alpha_tyvar [parrDataCon]
554 parrDataCon :: DataCon
555 parrDataCon = pcDataCon
557 alpha_tyvar -- forall'ed type variables
558 [intPrimTy, -- 1st argument: Int#
559 mkTyConApp -- 2nd argument: Array# a
564 -- check whether a type constructor is the constructor for parallel arrays
566 isPArrTyCon :: TyCon -> Bool
567 isPArrTyCon tc = tyConName tc == parrTyConName
569 -- fake array constructors
571 -- * these constructors are never really used to represent array values;
572 -- however, they are very convenient during desugaring (and, in particular,
573 -- in the pattern matching compiler) to treat array pattern just like
574 -- yet another constructor pattern
576 parrFakeCon :: Arity -> DataCon
577 parrFakeCon i | i > mAX_TUPLE_SIZE = mkPArrFakeCon i -- build one specially
578 parrFakeCon i = parrFakeConArr!i
580 -- pre-defined set of constructors
582 parrFakeConArr :: Array Int DataCon
583 parrFakeConArr = array (0, mAX_TUPLE_SIZE) [(i, mkPArrFakeCon i)
584 | i <- [0..mAX_TUPLE_SIZE]]
586 -- build a fake parallel array constructor for the given arity
588 mkPArrFakeCon :: Int -> DataCon
589 mkPArrFakeCon arity = data_con
591 data_con = pcDataCon name [tyvar] tyvarTys parrTyCon
592 tyvar = head alphaTyVars
593 tyvarTys = replicate arity $ mkTyVarTy tyvar
594 nameStr = mkFastString ("MkPArr" ++ show arity)
595 name = mkWiredInName gHC_PARR (mkOccNameFS dataName nameStr) unique
596 (ADataCon data_con) UserSyntax
597 unique = mkPArrDataConUnique arity
599 -- checks whether a data constructor is a fake constructor for parallel arrays
601 isPArrFakeCon :: DataCon -> Bool
602 isPArrFakeCon dcon = dcon == parrFakeCon (dataConSourceArity dcon)