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