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, mkAlgTyCon
97 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed, StrictnessMark(..) )
99 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTys,
100 mkArrowKinds, liftedTypeKind, unliftedTypeKind,
102 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
106 alpha_tyvar = [alphaTyVar]
108 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
112 %************************************************************************
114 \subsection{Wired in type constructors}
116 %************************************************************************
119 wiredInTyCons :: [TyCon]
120 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
122 data_tycons = genericTyCons ++
136 genericTyCons :: [TyCon]
137 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
140 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..mAX_TUPLE_SIZE] ]
141 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..mAX_TUPLE_SIZE] ]
145 %************************************************************************
147 \subsection{mkWiredInTyCon}
149 %************************************************************************
152 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
153 pcRecDataTyCon = pcTyCon DataTyCon Recursive
155 pcTyCon new_or_data is_rec name tyvars argvrcs cons
158 tycon = mkAlgTyCon name kind
164 [] -- No record selectors
169 mod = nameModule name
170 kind = mkArrowKinds (map tyVarKind tyvars) liftedTypeKind
171 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
173 -- We generate names for the generic to/from Ids by incrementing
174 -- the TyCon unique. So each Prelude tycon needs 3 slots, one
175 -- for itself and two more for the generic Ids.
176 mk_tc_gen_info mod tc_uniq tc_name tycon
177 = mkTyConGenInfo tycon [name1, name2]
179 tc_occ_name = nameOccName tc_name
180 occ_name1 = mkGenOcc1 tc_occ_name
181 occ_name2 = mkGenOcc2 tc_occ_name
182 fn1_key = incrUnique tc_uniq
183 fn2_key = incrUnique fn1_key
184 name1 = mkWiredInName mod occ_name1 fn1_key
185 name2 = mkWiredInName mod occ_name2 fn2_key
187 pcDataCon :: Name -> [TyVar] -> ThetaType -> [Type] -> TyCon -> DataCon
188 -- The unique is the first of two free uniques;
189 -- the first is used for the datacon itself and the worker;
190 -- the second is used for the wrapper.
192 pcDataCon name tyvars context arg_tys tycon
195 data_con = mkDataCon name
196 [ NotMarkedStrict | a <- arg_tys ]
197 [ {- no labelled fields -} ]
198 tyvars context [] [] arg_tys tycon work_id wrap_id
200 wrap_rdr = nameRdrName name
201 wrap_occ = rdrNameOcc wrap_rdr
203 mod = nameModule name
204 wrap_id = mkDataConWrapId data_con
206 work_occ = mkWorkerOcc wrap_occ
207 work_key = incrUnique (nameUnique name)
208 work_name = mkWiredInName mod work_occ work_key
209 work_id = mkDataConId work_name data_con
213 %************************************************************************
215 \subsection[TysWiredIn-tuples]{The tuple types}
217 %************************************************************************
220 tupleTyCon :: Boxity -> Arity -> TyCon
221 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
222 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
223 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
225 tupleCon :: Boxity -> Arity -> DataCon
226 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
227 tupleCon Boxed i = snd (boxedTupleArr ! i)
228 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
230 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
231 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
232 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
234 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
235 mk_tuple boxity arity = (tycon, tuple_con)
237 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
238 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
239 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
240 res_kind | isBoxed boxity = liftedTypeKind
241 | otherwise = unliftedTypeKind
243 tyvars | isBoxed boxity = take arity alphaTyVars
244 | otherwise = take arity openAlphaTyVars
246 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
247 tyvar_tys = mkTyVarTys tyvars
248 (mod_name, name_str) = mkTupNameStr boxity arity
249 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
250 tc_uniq = mkTupleTyConUnique boxity arity
251 dc_uniq = mkTupleDataConUnique boxity arity
252 mod = mkPrelModule mod_name
253 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
255 unitTyCon = tupleTyCon Boxed 0
256 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
258 pairTyCon = tupleTyCon Boxed 2
260 unboxedSingletonTyCon = tupleTyCon Unboxed 1
261 unboxedSingletonDataCon = tupleCon Unboxed 1
263 unboxedPairTyCon = tupleTyCon Unboxed 2
264 unboxedPairDataCon = tupleCon Unboxed 2
267 %************************************************************************
269 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
271 %************************************************************************
274 -- The Void type is represented as a data type with no constructors
275 -- It's a built in type (i.e. there's no way to define it in Haskell;
276 -- the nearest would be
278 -- data Void = -- No constructors!
280 -- ) It's lifted; there is only one value of this
281 -- type, namely "void", whose semantics is just bottom.
283 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
290 charTy = mkTyConTy charTyCon
292 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
293 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
295 stringTy = mkListTy charTy -- convenience only
299 intTy = mkTyConTy intTyCon
301 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
302 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
306 wordTy = mkTyConTy wordTyCon
308 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
309 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
313 addrTy = mkTyConTy addrTyCon
315 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
316 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
320 ptrTy = mkTyConTy ptrTyCon
322 ptrTyCon = pcNonRecDataTyCon ptrTyConName alpha_tyvar [(True,False)] [ptrDataCon]
323 ptrDataCon = pcDataCon ptrDataConName alpha_tyvar [] [addrPrimTy] ptrTyCon
327 funPtrTy = mkTyConTy funPtrTyCon
329 funPtrTyCon = pcNonRecDataTyCon funPtrTyConName alpha_tyvar [(True,False)] [funPtrDataCon]
330 funPtrDataCon = pcDataCon funPtrDataConName alpha_tyvar [] [addrPrimTy] funPtrTyCon
334 floatTy = mkTyConTy floatTyCon
336 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
337 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
341 doubleTy = mkTyConTy doubleTyCon
343 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
344 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
349 = pcNonRecDataTyCon stablePtrTyConName
350 alpha_tyvar [(True,False)] [stablePtrDataCon]
353 = pcDataCon stablePtrDataConName
354 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
359 = pcNonRecDataTyCon foreignObjTyConName
360 [] [] [foreignObjDataCon]
363 = pcDataCon foreignObjDataConName
364 [] [] [foreignObjPrimTy] foreignObjTyCon
369 = pcNonRecDataTyCon foreignPtrTyConName
370 alpha_tyvar [(True,False)] [foreignPtrDataCon]
373 = pcDataCon foreignPtrDataConName
374 alpha_tyvar [] [foreignObjPrimTy] foreignPtrTyCon
377 %************************************************************************
379 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
381 %************************************************************************
383 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
386 integerTy = mkTyConTy integerTyCon
388 integerTyCon = pcNonRecDataTyCon integerTyConName
389 [] [] [smallIntegerDataCon, largeIntegerDataCon]
391 smallIntegerDataCon = pcDataCon smallIntegerDataConName
392 [] [] [intPrimTy] integerTyCon
393 largeIntegerDataCon = pcDataCon largeIntegerDataConName
394 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
398 %************************************************************************
400 \subsection[TysWiredIn-Bool]{The @Bool@ type}
402 %************************************************************************
404 An ordinary enumeration type, but deeply wired in. There are no
405 magical operations on @Bool@ (just the regular Prelude code).
407 {\em BEGIN IDLE SPECULATION BY SIMON}
409 This is not the only way to encode @Bool@. A more obvious coding makes
410 @Bool@ just a boxed up version of @Bool#@, like this:
413 data Bool = MkBool Bool#
416 Unfortunately, this doesn't correspond to what the Report says @Bool@
417 looks like! Furthermore, we get slightly less efficient code (I
418 think) with this coding. @gtInt@ would look like this:
421 gtInt :: Int -> Int -> Bool
422 gtInt x y = case x of I# x# ->
424 case (gtIntPrim x# y#) of
428 Notice that the result of the @gtIntPrim@ comparison has to be turned
429 into an integer (here called @b#@), and returned in a @MkBool@ box.
431 The @if@ expression would compile to this:
434 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
437 I think this code is a little less efficient than the previous code,
438 but I'm not certain. At all events, corresponding with the Report is
439 important. The interesting thing is that the language is expressive
440 enough to describe more than one alternative; and that a type doesn't
441 necessarily need to be a straightforwardly boxed version of its
442 primitive counterpart.
444 {\em END IDLE SPECULATION BY SIMON}
447 boolTy = mkTyConTy boolTyCon
449 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
450 [] [] [falseDataCon, trueDataCon]
452 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
453 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
455 falseDataConId = dataConId falseDataCon
456 trueDataConId = dataConId trueDataCon
459 %************************************************************************
461 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
463 %************************************************************************
465 Special syntax, deeply wired in, but otherwise an ordinary algebraic
468 data [] a = [] | a : (List a)
470 data (,) a b = (,,) a b
475 mkListTy :: Type -> Type
476 mkListTy ty = mkTyConApp listTyCon [ty]
478 listTyCon = pcRecDataTyCon listTyConName
479 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
481 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
482 consDataCon = pcDataCon consDataConName
483 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
484 -- Interesting: polymorphic recursion would help here.
485 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
486 -- gets the over-specific type (Type -> Type)
489 %************************************************************************
491 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
493 %************************************************************************
495 The tuple types are definitely magic, because they form an infinite
500 They have a special family of type constructors, of type @TyCon@
501 These contain the tycon arity, but don't require a Unique.
504 They have a special family of constructors, of type
505 @Id@. Again these contain their arity but don't need a Unique.
508 There should be a magic way of generating the info tables and
509 entry code for all tuples.
511 But at the moment we just compile a Haskell source
512 file\srcloc{lib/prelude/...} containing declarations like:
515 data Tuple2 a b = Tup2 a b
516 data Tuple3 a b c = Tup3 a b c
517 data Tuple4 a b c d = Tup4 a b c d
520 The print-names associated with the magic @Id@s for tuple constructors
521 ``just happen'' to be the same as those generated by these
525 The instance environment should have a magic way to know
526 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
527 so on. \ToDo{Not implemented yet.}
530 There should also be a way to generate the appropriate code for each
531 of these instances, but (like the info tables and entry code) it is
532 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
536 mkTupleTy :: Boxity -> Int -> [Type] -> Type
537 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
539 unitTy = mkTupleTy Boxed 0 []
542 %************************************************************************
544 \subsection{Wired In Type Constructors for Representation Types}
546 %************************************************************************
548 The following code defines the wired in datatypes cross, plus, unit
549 and c_of needed for the generic methods.
551 Ok, so the basic story is that for each type constructor I need to
552 create 2 things - a TyCon and a DataCon and then we are basically
553 ok. There are going to be no arguments passed to these functions
554 because -well- there is nothing to pass to these functions.
558 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
560 crossDataCon :: DataCon
561 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
564 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
566 inlDataCon, inrDataCon :: DataCon
567 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
568 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
570 genUnitTyCon :: TyCon -- The "1" type constructor for generics
571 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
573 genUnitDataCon :: DataCon
574 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon