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.''
14 wiredInTyCons, genericTyCons,
34 falseDataCon, falseDataConId,
56 unitTyCon, unitDataConId, pairTyCon,
57 unboxedSingletonTyCon, unboxedSingletonDataCon,
58 unboxedPairTyCon, unboxedPairDataCon,
61 genUnitTyCon, genUnitDataCon,
62 plusTyCon, inrDataCon, inlDataCon,
63 crossTyCon, crossDataCon,
67 trueDataCon, trueDataConId,
75 #include "HsVersions.h"
77 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
78 import {-# SOURCE #-} Generics( mkTyConGenInfo )
85 import Constants ( mAX_TUPLE_SIZE )
86 import Module ( mkPrelModule )
87 import Name ( Name, nameRdrName, nameUnique, nameOccName,
88 nameModule, mkWiredInName )
89 import OccName ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
90 import RdrName ( rdrNameOcc )
91 import DataCon ( DataCon, mkDataCon, dataConId )
92 import Var ( TyVar, tyVarKind )
93 import TyCon ( TyCon, AlgTyConFlavour(..), tyConDataCons,
94 mkTupleTyCon, isUnLiftedTyCon, mkAlgTyCon
97 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed, StrictnessMark(..) )
99 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTys,
100 mkArrowKinds, liftedTypeKind, unliftedTypeKind,
103 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
108 alpha_tyvar = [alphaTyVar]
110 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
114 %************************************************************************
116 \subsection{Wired in type constructors}
118 %************************************************************************
121 wiredInTyCons :: [TyCon]
122 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
124 data_tycons = genericTyCons ++
138 genericTyCons :: [TyCon]
139 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
142 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..mAX_TUPLE_SIZE] ]
143 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..mAX_TUPLE_SIZE] ]
147 %************************************************************************
149 \subsection{mkWiredInTyCon}
151 %************************************************************************
154 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
155 pcRecDataTyCon = pcTyCon DataTyCon Recursive
157 pcTyCon new_or_data is_rec name tyvars argvrcs cons
160 tycon = mkAlgTyCon name kind
166 [] -- No record selectors
171 mod = nameModule name
172 kind = mkArrowKinds (map tyVarKind tyvars) liftedTypeKind
173 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
175 -- We generate names for the generic to/from Ids by incrementing
176 -- the TyCon unique. So each Prelude tycon needs 3 slots, one
177 -- for itself and two more for the generic Ids.
178 mk_tc_gen_info mod tc_uniq tc_name tycon
179 = mkTyConGenInfo tycon [name1, name2]
181 tc_occ_name = nameOccName tc_name
182 occ_name1 = mkGenOcc1 tc_occ_name
183 occ_name2 = mkGenOcc2 tc_occ_name
184 fn1_key = incrUnique tc_uniq
185 fn2_key = incrUnique fn1_key
186 name1 = mkWiredInName mod occ_name1 fn1_key
187 name2 = mkWiredInName mod occ_name2 fn2_key
189 pcDataCon :: Name -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
190 -- The unique is the first of two free uniques;
191 -- the first is used for the datacon itself and the worker;
192 -- the second is used for the wrapper.
194 pcDataCon name tyvars context arg_tys tycon
197 data_con = mkDataCon name
198 [ NotMarkedStrict | a <- arg_tys ]
199 [ {- no labelled fields -} ]
200 tyvars context [] [] arg_tys tycon work_id wrap_id
202 wrap_rdr = nameRdrName name
203 wrap_occ = rdrNameOcc wrap_rdr
205 mod = nameModule name
206 wrap_id = mkDataConWrapId data_con
208 work_occ = mkWorkerOcc wrap_occ
209 work_key = incrUnique (nameUnique name)
210 work_name = mkWiredInName mod work_occ work_key
211 work_id = mkDataConId work_name data_con
215 %************************************************************************
217 \subsection[TysWiredIn-tuples]{The tuple types}
219 %************************************************************************
222 tupleTyCon :: Boxity -> Arity -> TyCon
223 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
224 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
225 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
227 tupleCon :: Boxity -> Arity -> DataCon
228 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
229 tupleCon Boxed i = snd (boxedTupleArr ! i)
230 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
232 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
233 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
234 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
236 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
237 mk_tuple boxity arity = (tycon, tuple_con)
239 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
240 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
241 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
242 res_kind | isBoxed boxity = liftedTypeKind
243 | otherwise = unliftedTypeKind
245 tyvars | isBoxed boxity = take arity alphaTyVars
246 | otherwise = take arity openAlphaTyVars
248 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
249 tyvar_tys = mkTyVarTys tyvars
250 (mod_name, name_str) = mkTupNameStr boxity arity
251 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
252 tc_uniq = mkTupleTyConUnique boxity arity
253 dc_uniq = mkTupleDataConUnique boxity arity
254 mod = mkPrelModule mod_name
255 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
257 unitTyCon = tupleTyCon Boxed 0
258 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
260 pairTyCon = tupleTyCon Boxed 2
262 unboxedSingletonTyCon = tupleTyCon Unboxed 1
263 unboxedSingletonDataCon = tupleCon Unboxed 1
265 unboxedPairTyCon = tupleTyCon Unboxed 2
266 unboxedPairDataCon = tupleCon Unboxed 2
269 %************************************************************************
271 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
273 %************************************************************************
276 -- The Void type is represented as a data type with no constructors
277 -- It's a built in type (i.e. there's no way to define it in Haskell;
278 -- the nearest would be
280 -- data Void = -- No constructors!
282 -- ) It's lifted; there is only one value of this
283 -- type, namely "void", whose semantics is just bottom.
285 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
292 charTy = mkTyConTy charTyCon
294 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
295 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
297 stringTy = mkListTy charTy -- convenience only
301 intTy = mkTyConTy intTyCon
303 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
304 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
308 wordTy = mkTyConTy wordTyCon
310 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
311 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
315 addrTy = mkTyConTy addrTyCon
317 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
318 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
322 ptrTy = mkTyConTy ptrTyCon
324 ptrTyCon = pcNonRecDataTyCon ptrTyConName alpha_tyvar [(True,False)] [ptrDataCon]
325 ptrDataCon = pcDataCon ptrDataConName alpha_tyvar [] [addrPrimTy] ptrTyCon
329 funPtrTy = mkTyConTy funPtrTyCon
331 funPtrTyCon = pcNonRecDataTyCon funPtrTyConName alpha_tyvar [(True,False)] [funPtrDataCon]
332 funPtrDataCon = pcDataCon funPtrDataConName alpha_tyvar [] [addrPrimTy] funPtrTyCon
336 floatTy = mkTyConTy floatTyCon
338 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
339 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
343 doubleTy = mkTyConTy doubleTyCon
345 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
346 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
351 = pcNonRecDataTyCon stablePtrTyConName
352 alpha_tyvar [(True,False)] [stablePtrDataCon]
355 = pcDataCon stablePtrDataConName
356 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
361 = pcNonRecDataTyCon foreignObjTyConName
362 [] [] [foreignObjDataCon]
365 = pcDataCon foreignObjDataConName
366 [] [] [foreignObjPrimTy] foreignObjTyCon
371 = pcNonRecDataTyCon foreignPtrTyConName
372 alpha_tyvar [(True,False)] [foreignPtrDataCon]
375 = pcDataCon foreignPtrDataConName
376 alpha_tyvar [] [foreignObjPrimTy] foreignPtrTyCon
379 %************************************************************************
381 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
383 %************************************************************************
385 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
388 integerTy = mkTyConTy integerTyCon
390 integerTyCon = pcNonRecDataTyCon integerTyConName
391 [] [] [smallIntegerDataCon, largeIntegerDataCon]
393 smallIntegerDataCon = pcDataCon smallIntegerDataConName
394 [] [] [intPrimTy] integerTyCon
395 largeIntegerDataCon = pcDataCon largeIntegerDataConName
396 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
400 %************************************************************************
402 \subsection[TysWiredIn-Bool]{The @Bool@ type}
404 %************************************************************************
406 An ordinary enumeration type, but deeply wired in. There are no
407 magical operations on @Bool@ (just the regular Prelude code).
409 {\em BEGIN IDLE SPECULATION BY SIMON}
411 This is not the only way to encode @Bool@. A more obvious coding makes
412 @Bool@ just a boxed up version of @Bool#@, like this:
415 data Bool = MkBool Bool#
418 Unfortunately, this doesn't correspond to what the Report says @Bool@
419 looks like! Furthermore, we get slightly less efficient code (I
420 think) with this coding. @gtInt@ would look like this:
423 gtInt :: Int -> Int -> Bool
424 gtInt x y = case x of I# x# ->
426 case (gtIntPrim x# y#) of
430 Notice that the result of the @gtIntPrim@ comparison has to be turned
431 into an integer (here called @b#@), and returned in a @MkBool@ box.
433 The @if@ expression would compile to this:
436 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
439 I think this code is a little less efficient than the previous code,
440 but I'm not certain. At all events, corresponding with the Report is
441 important. The interesting thing is that the language is expressive
442 enough to describe more than one alternative; and that a type doesn't
443 necessarily need to be a straightforwardly boxed version of its
444 primitive counterpart.
446 {\em END IDLE SPECULATION BY SIMON}
449 boolTy = mkTyConTy boolTyCon
451 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
452 [] [] [falseDataCon, trueDataCon]
454 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
455 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
457 falseDataConId = dataConId falseDataCon
458 trueDataConId = dataConId trueDataCon
461 %************************************************************************
463 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
465 %************************************************************************
467 Special syntax, deeply wired in, but otherwise an ordinary algebraic
470 data [] a = [] | a : (List a)
472 data (,) a b = (,,) a b
477 mkListTy :: Type -> Type
478 mkListTy ty = mkTyConApp listTyCon [ty]
480 listTyCon = pcRecDataTyCon listTyConName
481 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
483 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
484 consDataCon = pcDataCon consDataConName
485 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
486 -- Interesting: polymorphic recursion would help here.
487 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
488 -- gets the over-specific type (Type -> Type)
491 %************************************************************************
493 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
495 %************************************************************************
497 The tuple types are definitely magic, because they form an infinite
502 They have a special family of type constructors, of type @TyCon@
503 These contain the tycon arity, but don't require a Unique.
506 They have a special family of constructors, of type
507 @Id@. Again these contain their arity but don't need a Unique.
510 There should be a magic way of generating the info tables and
511 entry code for all tuples.
513 But at the moment we just compile a Haskell source
514 file\srcloc{lib/prelude/...} containing declarations like:
517 data Tuple2 a b = Tup2 a b
518 data Tuple3 a b c = Tup3 a b c
519 data Tuple4 a b c d = Tup4 a b c d
522 The print-names associated with the magic @Id@s for tuple constructors
523 ``just happen'' to be the same as those generated by these
527 The instance environment should have a magic way to know
528 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
529 so on. \ToDo{Not implemented yet.}
532 There should also be a way to generate the appropriate code for each
533 of these instances, but (like the info tables and entry code) it is
534 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
538 mkTupleTy :: Boxity -> Int -> [Type] -> Type
539 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
541 unitTy = mkTupleTy Boxed 0 []
544 %************************************************************************
546 \subsection{Wired In Type Constructors for Representation Types}
548 %************************************************************************
550 The following code defines the wired in datatypes cross, plus, unit
551 and c_of needed for the generic methods.
553 Ok, so the basic story is that for each type constructor I need to
554 create 2 things - a TyCon and a DataCon and then we are basically
555 ok. There are going to be no arguments passed to these functions
556 because -well- there is nothing to pass to these functions.
560 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
562 crossDataCon :: DataCon
563 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
566 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
568 inlDataCon, inrDataCon :: DataCon
569 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
570 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
572 genUnitTyCon :: TyCon -- The "1" type constructor for generics
573 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
575 genUnitDataCon :: DataCon
576 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon