[project @ 2000-10-12 11:47:25 by sewardj]
[ghc-hetmet.git] / ghc / compiler / prelude / TysWiredIn.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1994-1998
3 %
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
5
6 This module is about types that can be defined in Haskell, but which
7 must be wired into the compiler nonetheless.
8
9 This module tracks the ``state interface'' document, ``GHC prelude:
10 types and operations.''
11
12 \begin{code}
13 module TysWiredIn (
14         wiredInTyCons, genericTyCons,
15
16         addrDataCon,
17         addrTy,
18         addrTyCon,
19         boolTy,
20         boolTyCon,
21         charDataCon,
22         charTy,
23         charTyCon,
24         consDataCon,
25         doubleDataCon,
26         doubleTy,
27         isDoubleTy,
28         doubleTyCon,
29         falseDataCon, falseDataConId,
30         floatDataCon,
31         floatTy,
32         isFloatTy,
33         floatTyCon,
34
35         intDataCon,
36         intTy,
37         intTyCon,
38         isIntTy,
39
40         integerTy,
41         integerTyCon,
42         smallIntegerDataCon,
43         largeIntegerDataCon,
44         isIntegerTy,
45
46         listTyCon,
47
48         mkListTy,
49         nilDataCon,
50
51         -- tuples
52         mkTupleTy,
53         tupleTyCon, tupleCon, 
54         unitTyCon, unitDataConId, pairTyCon, 
55         unboxedSingletonTyCon, unboxedSingletonDataCon,
56         unboxedPairTyCon, unboxedPairDataCon,
57
58         -- Generics
59         genUnitTyCon, genUnitDataCon, 
60         plusTyCon, inrDataCon, inlDataCon,
61         crossTyCon, crossDataCon,
62
63         stablePtrTyCon,
64         stringTy,
65         trueDataCon, trueDataConId,
66         unitTy,
67         voidTy,
68         wordDataCon,
69         wordTy,
70         wordTyCon,
71
72         isFFIArgumentTy,    -- :: Bool -> Type -> Bool
73         isFFIResultTy,      -- :: Type -> Bool
74         isFFIExternalTy,    -- :: Type -> Bool
75         isFFIDynArgumentTy, -- :: Type -> Bool
76         isFFIDynResultTy,   -- :: Type -> Bool
77         isFFILabelTy,       -- :: Type -> Bool
78         isAddrTy,           -- :: Type -> Bool
79         isForeignObjTy      -- :: Type -> Bool
80
81     ) where
82
83 #include "HsVersions.h"
84
85 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
86 import {-# SOURCE #-} Generics( mkTyConGenInfo )
87
88 -- friends:
89 import PrelNames
90 import TysPrim
91
92 -- others:
93 import Constants        ( mAX_TUPLE_SIZE )
94 import Module           ( Module, mkPrelModule )
95 import Name             ( mkWiredInTyConName, mkWiredInIdName, nameOccName )
96 import OccName          ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
97 import RdrName          ( RdrName, mkPreludeQual, rdrNameOcc, rdrNameModule )
98 import DataCon          ( DataCon, StrictnessMark(..),  mkDataCon, dataConId )
99 import Var              ( TyVar, tyVarKind )
100 import TyCon            ( TyCon, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
101                           mkSynTyCon, mkTupleTyCon, 
102                           isUnLiftedTyCon, mkAlgTyConRep,tyConName
103                         )
104
105 import BasicTypes       ( Arity, RecFlag(..), EP(..), Boxity(..), isBoxed )
106
107 import Type             ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys, 
108                           mkArrowKinds, boxedTypeKind, unboxedTypeKind,
109                           mkFunTy, mkFunTys, 
110                           splitTyConApp_maybe, repType, mkTyVarTy,
111                           TauType, ClassContext )
112 import Unique           ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
113 import PrelNames
114 import CmdLineOpts      ( DynFlags, dopt_GlasgowExts )
115 import Array
116 import Maybe            ( fromJust )
117 import FiniteMap        ( lookupFM )
118
119 alpha_tyvar       = [alphaTyVar]
120 alpha_ty          = [alphaTy]
121 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
122 \end{code}
123
124
125 %************************************************************************
126 %*                                                                      *
127 \subsection{Wired in type constructors}
128 %*                                                                      *
129 %************************************************************************
130
131 \begin{code}
132 wiredInTyCons :: [TyCon]
133 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
134
135 data_tycons = genericTyCons ++
136               [ addrTyCon
137               , boolTyCon
138               , charTyCon
139               , doubleTyCon
140               , floatTyCon
141               , intTyCon
142               , integerTyCon
143               , listTyCon
144               , wordTyCon
145               ]
146
147 genericTyCons :: [TyCon]
148 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
149
150
151 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..37] ]
152 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..37] ]
153 \end{code}
154
155
156 %************************************************************************
157 %*                                                                      *
158 \subsection{mkWiredInTyCon}
159 %*                                                                      *
160 %************************************************************************
161
162 \begin{code}
163 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
164 pcRecDataTyCon = pcTyCon DataTyCon Recursive
165
166 pcTyCon new_or_data is_rec key rdr_name tyvars argvrcs cons
167   = tycon
168   where
169     tycon = mkAlgTyConRep name kind
170                 tyvars
171                 []              -- No context
172                 argvrcs
173                 cons
174                 (length cons)
175                 []              -- No derivings
176                 new_or_data
177                 is_rec
178                 gen_info
179
180     mod      = mkPrelModule (rdrNameModule rdr_name)
181     occ      = rdrNameOcc rdr_name
182     name     = mkWiredInTyConName key mod occ tycon
183     kind     = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
184     gen_info = mk_tc_gen_info mod key name tycon
185
186 pcDataCon :: Unique     -- DataConKey
187           -> RdrName    -- Qualified
188           -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
189 -- The unique is the first of two free uniques;
190 -- the first is used for the datacon itself and the worker;
191 -- the second is used for the wrapper.
192
193 pcDataCon wrap_key rdr_name tyvars context arg_tys tycon
194   = data_con
195   where
196     mod      = mkPrelModule (rdrNameModule rdr_name)
197     wrap_occ = rdrNameOcc rdr_name
198
199     data_con = mkDataCon wrap_name
200                 [ NotMarkedStrict | a <- arg_tys ]
201                 [ {- no labelled fields -} ]
202                 tyvars context [] [] arg_tys tycon work_id wrap_id
203
204     work_occ  = mkWorkerOcc wrap_occ
205     work_key  = incrUnique wrap_key
206     work_name = mkWiredInIdName work_key mod work_occ work_id
207     work_id   = mkDataConId work_name data_con
208
209     wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
210     wrap_id   = mkDataConWrapId data_con
211 \end{code}
212
213
214 %************************************************************************
215 %*                                                                      *
216 \subsection[TysWiredIn-tuples]{The tuple types}
217 %*                                                                      *
218 %************************************************************************
219
220 \begin{code}
221 tupleTyCon :: Boxity -> Arity -> TyCon
222 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i)      -- Build one specially
223 tupleTyCon Boxed   i = fst (boxedTupleArr   ! i)
224 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
225
226 tupleCon :: Boxity -> Arity -> DataCon
227 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i)        -- Build one specially
228 tupleCon Boxed   i = snd (boxedTupleArr   ! i)
229 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
230
231 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
232 boxedTupleArr   = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i)   | i <- [0..mAX_TUPLE_SIZE]]
233 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
234
235 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
236 mk_tuple boxity arity = (tycon, tuple_con)
237   where
238         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info 
239         tc_name = mkWiredInTyConName tc_uniq mod (mkOccFS tcName name_str) tycon
240         tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
241         res_kind | isBoxed boxity = boxedTypeKind
242                  | otherwise      = unboxedTypeKind
243
244         tyvars   | isBoxed boxity = take arity alphaTyVars
245                  | otherwise      = take arity openAlphaTyVars
246
247         tuple_con = pcDataCon dc_uniq rdr_name tyvars [] tyvar_tys tycon
248         tyvar_tys = mkTyVarTys tyvars
249         (mod_name, name_str) = mkTupNameStr boxity arity
250         rdr_name  = mkPreludeQual dataName mod_name name_str
251         tc_uniq   = mkTupleTyConUnique   boxity arity
252         dc_uniq   = mkTupleDataConUnique boxity arity
253         mod       = mkPrelModule mod_name
254         gen_info  = mk_tc_gen_info mod tc_uniq tc_name tycon
255
256 mk_tc_gen_info mod tc_uniq tc_name tycon
257   = gen_info
258   where
259         tc_occ_name = nameOccName tc_name
260         occ_name1   = mkGenOcc1 tc_occ_name
261         occ_name2   = mkGenOcc2 tc_occ_name
262         fn1_key     = incrUnique tc_uniq
263         fn2_key     = incrUnique fn1_key
264         name1       = mkWiredInIdName fn1_key mod occ_name1 id1
265         name2       = mkWiredInIdName fn2_key mod occ_name2 id2
266         gen_info    = mkTyConGenInfo tycon name1 name2
267         Just (EP id1 id2) = gen_info
268
269 unitTyCon     = tupleTyCon Boxed 0
270 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
271
272 pairTyCon = tupleTyCon Boxed 2
273
274 unboxedSingletonTyCon   = tupleTyCon Unboxed 1
275 unboxedSingletonDataCon = tupleCon   Unboxed 1
276
277 unboxedPairTyCon   = tupleTyCon Unboxed 2
278 unboxedPairDataCon = tupleCon   Unboxed 2
279 \end{code}
280
281 %************************************************************************
282 %*                                                                      *
283 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
284 %*                                                                      *
285 %************************************************************************
286
287 \begin{code}
288 -- The Void type is represented as a data type with no constructors
289 -- It's a built in type (i.e. there's no way to define it in Haskell;
290 --      the nearest would be
291 --
292 --              data Void =             -- No constructors!
293 --
294 -- ) It's boxed; there is only one value of this
295 -- type, namely "void", whose semantics is just bottom.
296 --
297 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
298 -- voidTy using ().
299 voidTy = unitTy
300 \end{code}
301
302
303 \begin{code}
304 charTy = mkTyConTy charTyCon
305
306 charTyCon   = pcNonRecDataTyCon charTyConKey charTyCon_RDR [] [] [charDataCon]
307 charDataCon = pcDataCon charDataConKey charDataCon_RDR [] [] [charPrimTy] charTyCon
308
309 stringTy = mkListTy charTy -- convenience only
310 \end{code}
311
312 \begin{code}
313 intTy = mkTyConTy intTyCon 
314
315 intTyCon = pcNonRecDataTyCon intTyConKey intTyCon_RDR [] [] [intDataCon]
316 intDataCon = pcDataCon intDataConKey mkInt_RDR [] [] [intPrimTy] intTyCon
317
318 isIntTy :: Type -> Bool
319 isIntTy = isTyCon intTyConKey
320 \end{code}
321
322 \begin{code}
323
324 wordTy = mkTyConTy wordTyCon
325
326 wordTyCon = pcNonRecDataTyCon wordTyConKey wordTyCon_RDR [] [] [wordDataCon]
327 wordDataCon = pcDataCon wordDataConKey wordDataCon_RDR [] [] [wordPrimTy] wordTyCon
328 \end{code}
329
330 \begin{code}
331 addrTy = mkTyConTy addrTyCon
332
333 addrTyCon = pcNonRecDataTyCon addrTyConKey addrTyCon_RDR [] [] [addrDataCon]
334 addrDataCon = pcDataCon addrDataConKey addrDataCon_RDR [] [] [addrPrimTy] addrTyCon
335
336 isAddrTy :: Type -> Bool
337 isAddrTy = isTyCon addrTyConKey
338 \end{code}
339
340 \begin{code}
341 floatTy = mkTyConTy floatTyCon
342
343 floatTyCon   = pcNonRecDataTyCon floatTyConKey   floatTyCon_RDR   [] [] [floatDataCon]
344 floatDataCon = pcDataCon         floatDataConKey floatDataCon_RDR [] [] [floatPrimTy] floatTyCon
345
346 isFloatTy :: Type -> Bool
347 isFloatTy = isTyCon floatTyConKey
348 \end{code}
349
350 \begin{code}
351 doubleTy = mkTyConTy doubleTyCon
352
353 isDoubleTy :: Type -> Bool
354 isDoubleTy = isTyCon doubleTyConKey
355
356 doubleTyCon   = pcNonRecDataTyCon doubleTyConKey   doubleTyCon_RDR     [] [] [doubleDataCon]
357 doubleDataCon = pcDataCon         doubleDataConKey doubleDataCon_RDR [] [] [doublePrimTy] doubleTyCon
358 \end{code}
359
360 \begin{code}
361 stablePtrTyCon
362   = pcNonRecDataTyCon stablePtrTyConKey stablePtrTyCon_RDR
363         alpha_tyvar [(True,False)] [stablePtrDataCon]
364   where
365     stablePtrDataCon
366       = pcDataCon stablePtrDataConKey stablePtrDataCon_RDR
367             alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
368 \end{code}
369
370 \begin{code}
371 foreignObjTyCon
372   = pcNonRecDataTyCon foreignObjTyConKey foreignObjTyCon_RDR
373         [] [] [foreignObjDataCon]
374   where
375     foreignObjDataCon
376       = pcDataCon foreignObjDataConKey foreignObjDataCon_RDR
377             [] [] [foreignObjPrimTy] foreignObjTyCon
378
379 isForeignObjTy :: Type -> Bool
380 isForeignObjTy = isTyCon foreignObjTyConKey
381 \end{code}
382
383 %************************************************************************
384 %*                                                                      *
385 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
386 %*                                                                      *
387 %************************************************************************
388
389 @Integer@ and its pals are not really primitive.  @Integer@ itself, first:
390 \begin{code}
391 integerTy :: Type
392 integerTy = mkTyConTy integerTyCon
393
394 integerTyCon = pcNonRecDataTyCon integerTyConKey integerTyCon_RDR
395                    [] [] [smallIntegerDataCon, largeIntegerDataCon]
396
397 smallIntegerDataCon = pcDataCon smallIntegerDataConKey smallIntegerDataCon_RDR
398                 [] [] [intPrimTy] integerTyCon
399 largeIntegerDataCon = pcDataCon largeIntegerDataConKey largeIntegerDataCon_RDR
400                 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
401
402
403 isIntegerTy :: Type -> Bool
404 isIntegerTy = isTyCon integerTyConKey
405 \end{code}
406
407
408 %************************************************************************
409 %*                                                                      *
410 \subsection[TysWiredIn-ext-type]{External types}
411 %*                                                                      *
412 %************************************************************************
413
414 The compiler's foreign function interface supports the passing of a
415 restricted set of types as arguments and results (the restricting factor
416 being the )
417
418 \begin{code}
419 isFFIArgumentTy :: DynFlags -> Bool -> Type -> Bool
420 -- Checks for valid argument type for a 'foreign import'
421 isFFIArgumentTy dflags is_safe ty 
422    = checkRepTyCon (legalOutgoingTyCon dflags is_safe) ty
423
424 isFFIExternalTy :: Type -> Bool
425 -- Types that are allowed as arguments of a 'foreign export'
426 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
427
428 isFFIResultTy :: Type -> Bool
429 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
430 -- Maybe we should distinguish between import and export, but 
431 -- here we just choose the more restrictive 'incoming' predicate
432 -- But we allow () as well
433 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
434
435 isFFIDynArgumentTy :: Type -> Bool
436 -- The argument type of a foreign import dynamic must be either Addr, or
437 -- a newtype of Addr.
438 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
439
440 isFFIDynResultTy :: Type -> Bool
441 -- The result type of a foreign export dynamic must be either Addr, or
442 -- a newtype of Addr.
443 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
444
445 isFFILabelTy :: Type -> Bool
446 -- The type of a foreign label must be either Addr, or
447 -- a newtype of Addr.
448 isFFILabelTy = checkRepTyCon (== addrTyCon)
449
450 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
451         -- look through newtypes
452 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
453
454 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
455 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
456                                 Just (tycon, _) -> check_tc tycon
457                                 Nothing         -> False
458
459 isTyCon :: Unique -> Type -> Bool
460 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
461 \end{code}
462
463 ----------------------------------------------
464 These chaps do the work; they are not exported
465 ----------------------------------------------
466
467 \begin{code}
468 legalIncomingTyCon :: TyCon -> Bool
469 -- It's illegal to return foreign objects and (mutable)
470 -- bytearrays from a _ccall_ / foreign declaration
471 -- (or be passed them as arguments in foreign exported functions).
472 legalIncomingTyCon tc
473   | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, 
474                                               mutableByteArrayTyConKey ] 
475   = False
476   -- It's also illegal to make foreign exports that take unboxed
477   -- arguments.  The RTS API currently can't invoke such things.  --SDM 7/2000
478   | otherwise
479   = boxedMarshalableTyCon tc
480
481 legalOutgoingTyCon :: DynFlags -> Bool -> TyCon -> Bool
482 -- Checks validity of types going from Haskell -> external world
483 -- The boolean is true for a 'safe' call (when we don't want to
484 -- pass Haskell pointers to the world)
485 legalOutgoingTyCon dflags be_safe tc
486   | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
487   = False
488   | otherwise
489   = marshalableTyCon dflags tc
490
491 marshalableTyCon dflags tc
492   =  (dopt_GlasgowExts dflags && isUnLiftedTyCon tc)
493   || boxedMarshalableTyCon tc
494
495 boxedMarshalableTyCon tc
496    = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
497                          , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
498                          , floatTyConKey, doubleTyConKey
499                          , addrTyConKey, charTyConKey, foreignObjTyConKey
500                          , stablePtrTyConKey
501                          , byteArrayTyConKey, mutableByteArrayTyConKey
502                          , boolTyConKey
503                          ]
504 \end{code}
505
506
507 %************************************************************************
508 %*                                                                      *
509 \subsection[TysWiredIn-Bool]{The @Bool@ type}
510 %*                                                                      *
511 %************************************************************************
512
513 An ordinary enumeration type, but deeply wired in.  There are no
514 magical operations on @Bool@ (just the regular Prelude code).
515
516 {\em BEGIN IDLE SPECULATION BY SIMON}
517
518 This is not the only way to encode @Bool@.  A more obvious coding makes
519 @Bool@ just a boxed up version of @Bool#@, like this:
520 \begin{verbatim}
521 type Bool# = Int#
522 data Bool = MkBool Bool#
523 \end{verbatim}
524
525 Unfortunately, this doesn't correspond to what the Report says @Bool@
526 looks like!  Furthermore, we get slightly less efficient code (I
527 think) with this coding. @gtInt@ would look like this:
528
529 \begin{verbatim}
530 gtInt :: Int -> Int -> Bool
531 gtInt x y = case x of I# x# ->
532             case y of I# y# ->
533             case (gtIntPrim x# y#) of
534                 b# -> MkBool b#
535 \end{verbatim}
536
537 Notice that the result of the @gtIntPrim@ comparison has to be turned
538 into an integer (here called @b#@), and returned in a @MkBool@ box.
539
540 The @if@ expression would compile to this:
541 \begin{verbatim}
542 case (gtInt x y) of
543   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
544 \end{verbatim}
545
546 I think this code is a little less efficient than the previous code,
547 but I'm not certain.  At all events, corresponding with the Report is
548 important.  The interesting thing is that the language is expressive
549 enough to describe more than one alternative; and that a type doesn't
550 necessarily need to be a straightforwardly boxed version of its
551 primitive counterpart.
552
553 {\em END IDLE SPECULATION BY SIMON}
554
555 \begin{code}
556 boolTy = mkTyConTy boolTyCon
557
558 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey 
559                     boolTyCon_RDR [] [] [falseDataCon, trueDataCon]
560
561 falseDataCon = pcDataCon falseDataConKey false_RDR [] [] [] boolTyCon
562 trueDataCon  = pcDataCon trueDataConKey  true_RDR  [] [] [] boolTyCon
563
564 falseDataConId = dataConId falseDataCon
565 trueDataConId  = dataConId trueDataCon
566 \end{code}
567
568 %************************************************************************
569 %*                                                                      *
570 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
571 %*                                                                      *
572 %************************************************************************
573
574 Special syntax, deeply wired in, but otherwise an ordinary algebraic
575 data types:
576 \begin{verbatim}
577 data [] a = [] | a : (List a)
578 data () = ()
579 data (,) a b = (,,) a b
580 ...
581 \end{verbatim}
582
583 \begin{code}
584 mkListTy :: Type -> Type
585 mkListTy ty = mkTyConApp listTyCon [ty]
586
587 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
588
589 listTyCon = pcRecDataTyCon listTyConKey listTyCon_RDR
590                         alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
591
592 nilDataCon  = pcDataCon nilDataConKey  nil_RDR alpha_tyvar [] [] listTyCon
593 consDataCon = pcDataCon consDataConKey cons_RDR
594                 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
595 -- Interesting: polymorphic recursion would help here.
596 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
597 -- gets the over-specific type (Type -> Type)
598 \end{code}
599
600 %************************************************************************
601 %*                                                                      *
602 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
603 %*                                                                      *
604 %************************************************************************
605
606 The tuple types are definitely magic, because they form an infinite
607 family.
608
609 \begin{itemize}
610 \item
611 They have a special family of type constructors, of type @TyCon@
612 These contain the tycon arity, but don't require a Unique.
613
614 \item
615 They have a special family of constructors, of type
616 @Id@. Again these contain their arity but don't need a Unique.
617
618 \item
619 There should be a magic way of generating the info tables and
620 entry code for all tuples.
621
622 But at the moment we just compile a Haskell source
623 file\srcloc{lib/prelude/...} containing declarations like:
624 \begin{verbatim}
625 data Tuple0             = Tup0
626 data Tuple2  a b        = Tup2  a b
627 data Tuple3  a b c      = Tup3  a b c
628 data Tuple4  a b c d    = Tup4  a b c d
629 ...
630 \end{verbatim}
631 The print-names associated with the magic @Id@s for tuple constructors
632 ``just happen'' to be the same as those generated by these
633 declarations.
634
635 \item
636 The instance environment should have a magic way to know
637 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
638 so on. \ToDo{Not implemented yet.}
639
640 \item
641 There should also be a way to generate the appropriate code for each
642 of these instances, but (like the info tables and entry code) it is
643 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
644 \end{itemize}
645
646 \begin{code}
647 mkTupleTy :: Boxity -> Int -> [Type] -> Type
648 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
649
650 unitTy    = mkTupleTy Boxed 0 []
651 \end{code}
652
653 %************************************************************************
654 %*                                                                      *
655 \subsection{Wired In Type Constructors for Representation Types}
656 %*                                                                      *
657 %************************************************************************
658
659 The following code defines the wired in datatypes cross, plus, unit
660 and c_of needed for the generic methods.
661
662 Ok, so the basic story is that for each type constructor I need to
663 create 2 things - a TyCon and a DataCon and then we are basically
664 ok. There are going to be no arguments passed to these functions
665 because -well- there is nothing to pass to these functions.
666
667 \begin{code}
668 crossTyCon :: TyCon
669 crossTyCon = pcNonRecDataTyCon crossTyConKey crossTyCon_RDR alpha_beta_tyvars [] [crossDataCon]
670
671 crossDataCon :: DataCon
672 crossDataCon = pcDataCon crossDataConKey crossDataCon_RDR alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
673
674 plusTyCon :: TyCon
675 plusTyCon = pcNonRecDataTyCon plusTyConKey plusTyCon_RDR alpha_beta_tyvars [] [inlDataCon, inrDataCon]
676
677 inlDataCon, inrDataCon :: DataCon
678 inlDataCon = pcDataCon inlDataConKey inlDataCon_RDR alpha_beta_tyvars [] [alphaTy] plusTyCon
679 inrDataCon = pcDataCon inrDataConKey inrDataCon_RDR alpha_beta_tyvars [] [betaTy]  plusTyCon
680
681 genUnitTyCon :: TyCon   -- The "1" type constructor for generics
682 genUnitTyCon = pcNonRecDataTyCon genUnitTyConKey genUnitTyCon_RDR [] [] [genUnitDataCon]
683
684 genUnitDataCon :: DataCon
685 genUnitDataCon = pcDataCon genUnitDataConKey genUnitDataCon_RDR [] [] [] genUnitTyCon
686 \end{code}
687
688
689
690
691