[project @ 1999-03-02 15:43:27 by sof]
[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         addrDataCon,
15         addrTy,
16         addrTyCon,
17         boolTy,
18         boolTyCon,
19         charDataCon,
20         charTy,
21         charTyCon,
22         consDataCon,
23         doubleDataCon,
24         doubleTy,
25         isDoubleTy,
26         doubleTyCon,
27         falseDataCon,
28         floatDataCon,
29         floatTy,
30         isFloatTy,
31         floatTyCon,
32
33         intDataCon,
34         intTy,
35         intTyCon,
36         isIntTy,
37         inIntRange,
38
39         int8TyCon,
40         int16TyCon,
41         int32TyCon,
42
43         int64TyCon,
44
45         integerTy,
46         integerTyCon,
47         smallIntegerDataCon,
48         largeIntegerDataCon,
49         isIntegerTy,
50
51         listTyCon,
52
53         mkListTy,
54         nilDataCon,
55
56         -- tuples
57         mkTupleTy,
58         tupleTyCon, tupleCon, unitTyCon, unitDataCon, pairTyCon, pairDataCon,
59
60         -- unboxed tuples
61         mkUnboxedTupleTy,
62         unboxedTupleTyCon, unboxedTupleCon, 
63         unboxedPairTyCon, unboxedPairDataCon,
64
65         stablePtrTyCon,
66         stringTy,
67         trueDataCon,
68         unitTy,
69         voidTy,
70         wordDataCon,
71         wordTy,
72         wordTyCon,
73
74         word8TyCon,
75         word16TyCon,
76         word32TyCon,
77         word64TyCon,
78         
79         isFFIArgumentTy,  -- :: Type -> Bool
80         isFFIResultTy,    -- :: Type -> Bool
81         isFFIExternalTy,  -- :: Type -> Bool
82         isAddrTy,         -- :: Type -> Bool
83
84     ) where
85
86 #include "HsVersions.h"
87
88 import {-# SOURCE #-} MkId( mkDataConId )
89
90 -- friends:
91 import PrelMods
92 import TysPrim
93
94 -- others:
95 import Constants        ( mAX_TUPLE_SIZE )
96 import Module           ( Module )
97 import Name             ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, dataName )
98 import DataCon          ( DataCon, mkDataCon )
99 import Var              ( TyVar, tyVarKind )
100 import TyCon            ( TyCon, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
101 import BasicTypes       ( Arity, NewOrData(..), 
102                           RecFlag(..), StrictnessMark(..) )
103 import Type             ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys, 
104                           mkArrowKinds, boxedTypeKind, unboxedTypeKind,
105                           mkFunTy, mkFunTys, isUnLiftedType,
106                           splitTyConApp_maybe, splitAlgTyConApp_maybe,
107                           ThetaType, TauType )
108 import PrimRep          ( PrimRep(..) )
109 import Unique
110 import CmdLineOpts      ( opt_GlasgowExts )
111 import Util             ( assoc )
112 import Panic            ( panic )
113 import Array
114
115 alpha_tyvar       = [alphaTyVar]
116 alpha_ty          = [alphaTy]
117 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
118
119 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
120         :: Unique{-TyConKey-} -> Module -> FAST_STRING
121         -> [TyVar] -> [DataCon] -> TyCon
122
123 pcRecDataTyCon    = pcTyCon DataType Recursive
124 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
125 pcNonRecNewTyCon  = pcTyCon NewType  NonRecursive
126
127 pcTyCon new_or_data is_rec key mod str tyvars cons
128   = tycon
129   where
130     tycon = mkAlgTyCon name kind 
131                 tyvars 
132                 []              -- No context
133                 cons
134                 []              -- No derivings
135                 Nothing         -- Not a dictionary
136                 new_or_data
137                 is_rec
138
139     name = mkWiredInTyConName key mod str tycon
140     kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
141
142 pcSynTyCon key mod str kind arity tyvars expansion
143   = tycon
144   where
145     tycon = mkSynTyCon name kind arity tyvars expansion
146     name  = mkWiredInTyConName key mod str tycon
147
148 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
149           -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
150 pcDataCon key mod str tyvars context arg_tys tycon
151   = data_con
152   where
153     data_con = mkDataCon name 
154                 [ NotMarkedStrict | a <- arg_tys ]
155                 [ {- no labelled fields -} ]
156                 tyvars context [] [] arg_tys tycon id
157     name = mkWiredInIdName key mod (mkSrcOccFS dataName str) id
158     id   = mkDataConId data_con
159 \end{code}
160
161 %************************************************************************
162 %*                                                                      *
163 \subsection[TysWiredIn-tuples]{The tuple types}
164 %*                                                                      *
165 %************************************************************************
166
167 \begin{code}
168 tupleTyCon :: Arity -> TyCon
169 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i)    -- Build one specially
170              | otherwise          = tupleTyConArr!i
171
172 tupleCon :: Arity -> DataCon
173 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i)      -- Build one specially
174            | otherwise          = tupleConArr!i
175
176 tupleTyCons :: [TyCon]
177 tupleTyCons = elems tupleTyConArr
178
179 tupleTyConArr :: Array Int TyCon
180 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
181
182 tupleConArr :: Array Int DataCon
183 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
184
185 tuples :: [(TyCon,DataCon)]
186 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
187
188 mk_tuple :: Int -> (TyCon,DataCon)
189 mk_tuple arity = (tycon, tuple_con)
190   where
191         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
192         tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
193         tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
194
195         tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
196         tyvars    = take arity alphaTyVars
197         tyvar_tys = mkTyVarTys tyvars
198         (mod_name, name_str) = mkTupNameStr arity
199         tc_uniq   = mkTupleTyConUnique   arity
200         dc_uniq   = mkTupleDataConUnique arity
201
202 unitTyCon = tupleTyCon 0
203 pairTyCon = tupleTyCon 2
204
205 unitDataCon = tupleCon 0
206 pairDataCon = tupleCon 2
207 \end{code}
208
209 %************************************************************************
210 %*                                                                      *
211 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
212 %*                                                                      *
213 %************************************************************************
214
215 \begin{code}
216 unboxedTupleTyCon :: Arity -> TyCon
217 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
218                     | otherwise          = unboxedTupleTyConArr!i
219
220 unboxedTupleCon :: Arity -> DataCon
221 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
222                   | otherwise          = unboxedTupleConArr!i
223
224 unboxedTupleTyConArr :: Array Int TyCon
225 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
226
227 unboxedTupleConArr :: Array Int DataCon
228 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
229
230 ubx_tuples :: [(TyCon,DataCon)]
231 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
232
233 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
234 mk_unboxed_tuple arity = (tycon, tuple_con)
235   where
236         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
237         tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
238         tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
239
240         tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
241         tyvars    = take arity openAlphaTyVars
242         tyvar_tys = mkTyVarTys tyvars
243         (mod_name, name_str) = mkUbxTupNameStr arity
244         tc_uniq   = mkUbxTupleTyConUnique   arity
245         dc_uniq   = mkUbxTupleDataConUnique arity
246
247 unboxedPairTyCon   = unboxedTupleTyCon 2
248 unboxedPairDataCon = unboxedTupleCon 2
249 \end{code}
250
251 %************************************************************************
252 %*                                                                      *
253 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
254 %*                                                                      *
255 %************************************************************************
256
257 \begin{code}
258 -- The Void type is represented as a data type with no constructors
259 -- It's a built in type (i.e. there's no way to define it in Haskell;
260 --      the nearest would be
261 --
262 --              data Void =             -- No constructors!
263 --
264 -- ) It's boxed; there is only one value of this
265 -- type, namely "void", whose semantics is just bottom.
266 --
267 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
268 -- voidTy using ().
269 voidTy = unitTy
270 \end{code}
271
272
273 \begin{code}
274 charTy = mkTyConTy charTyCon
275
276 charTyCon = pcNonRecDataTyCon charTyConKey  pREL_BASE  SLIT("Char") [] [charDataCon]
277 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
278
279 stringTy = mkListTy charTy -- convenience only
280 \end{code}
281
282 \begin{code}
283 intTy = mkTyConTy intTyCon 
284
285 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
286 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
287
288 isIntTy :: Type -> Bool
289 isIntTy ty
290   = case (splitAlgTyConApp_maybe ty) of
291         Just (tycon, [], _) -> getUnique tycon == intTyConKey
292         _                   -> False
293
294 inIntRange :: Integer -> Bool   -- Tells if an integer lies in the legal range of Ints
295 inIntRange i = (min_int <= i) && (i <= max_int)
296
297 max_int, min_int :: Integer
298 max_int = toInteger maxInt  
299 min_int = toInteger minInt
300
301 int8TyCon = pcNonRecDataTyCon int8TyConKey iNT SLIT("Int8") [] [int8DataCon]
302   where
303    int8DataCon = pcDataCon int8DataConKey iNT SLIT("I8#") [] [] [intPrimTy] int8TyCon
304
305 int16TyCon = pcNonRecDataTyCon int16TyConKey iNT SLIT("Int16") [] [int16DataCon]
306   where
307    int16DataCon = pcDataCon int16DataConKey iNT SLIT("I16#") [] [] [intPrimTy] int16TyCon
308
309 int32TyCon = pcNonRecDataTyCon int32TyConKey iNT SLIT("Int32") [] [int32DataCon]
310   where
311    int32DataCon = pcDataCon int32DataConKey iNT SLIT("I32#") [] [] [intPrimTy] int32TyCon
312
313 int64TyCon = pcNonRecDataTyCon int64TyConKey pREL_ADDR SLIT("Int64") [] [int64DataCon]
314   where
315    int64DataCon = pcDataCon int64DataConKey pREL_ADDR SLIT("I64#") [] [] [int64PrimTy] int64TyCon
316 \end{code}
317
318 \begin{code}
319
320 wordTy = mkTyConTy wordTyCon
321
322 wordTyCon = pcNonRecDataTyCon wordTyConKey   pREL_ADDR SLIT("Word") [] [wordDataCon]
323 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
324
325 word8TyCon = pcNonRecDataTyCon word8TyConKey   wORD SLIT("Word8") [] [word8DataCon]
326   where
327    word8DataCon = pcDataCon word8DataConKey wORD SLIT("W8#") [] [] [wordPrimTy] word8TyCon
328
329 word16TyCon = pcNonRecDataTyCon word16TyConKey   wORD SLIT("Word16") [] [word16DataCon]
330   where
331    word16DataCon = pcDataCon word16DataConKey wORD SLIT("W16#") [] [] [wordPrimTy] word16TyCon
332
333 word32TyCon = pcNonRecDataTyCon word32TyConKey   wORD SLIT("Word32") [] [word32DataCon]
334   where
335    word32DataCon = pcDataCon word32DataConKey wORD SLIT("W32#") [] [] [wordPrimTy] word32TyCon
336
337 word64TyCon = pcNonRecDataTyCon word64TyConKey   pREL_ADDR SLIT("Word64") [] [word64DataCon]
338   where
339     word64DataCon = pcDataCon word64DataConKey pREL_ADDR SLIT("W64#") [] [] [word64PrimTy] word64TyCon
340 \end{code}
341
342 \begin{code}
343 addrTy = mkTyConTy addrTyCon
344
345 addrTyCon = pcNonRecDataTyCon addrTyConKey   pREL_ADDR SLIT("Addr") [] [addrDataCon]
346 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
347
348 isAddrTy :: Type -> Bool
349 isAddrTy ty
350   = case (splitAlgTyConApp_maybe ty) of
351         Just (tycon, [], _) -> getUnique tycon == addrTyConKey
352         _                   -> False
353
354 \end{code}
355
356 \begin{code}
357 floatTy = mkTyConTy floatTyCon
358
359 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
360 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
361
362 isFloatTy :: Type -> Bool
363 isFloatTy ty
364   = case (splitAlgTyConApp_maybe ty) of
365         Just (tycon, [], _) -> getUnique tycon == floatTyConKey
366         _                   -> False
367
368 \end{code}
369
370 \begin{code}
371 doubleTy = mkTyConTy doubleTyCon
372
373 isDoubleTy :: Type -> Bool
374 isDoubleTy ty
375   = case (splitAlgTyConApp_maybe ty) of
376         Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
377         _                   -> False
378
379 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
380 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
381 \end{code}
382
383 \begin{code}
384 stablePtrTyCon
385   = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
386         alpha_tyvar [stablePtrDataCon]
387   where
388     stablePtrDataCon
389       = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
390             alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
391 \end{code}
392
393 \begin{code}
394 foreignObjTyCon
395   = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
396         [] [foreignObjDataCon]
397   where
398     foreignObjDataCon
399       = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
400             [] [] [foreignObjPrimTy] foreignObjTyCon
401 \end{code}
402
403 %************************************************************************
404 %*                                                                      *
405 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
406 %*                                                                      *
407 %************************************************************************
408
409 @Integer@ and its pals are not really primitive.  @Integer@ itself, first:
410 \begin{code}
411 integerTy :: Type
412 integerTy = mkTyConTy integerTyCon
413
414 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [smallIntegerDataCon, largeIntegerDataCon]
415
416 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_BASE SLIT("S#")
417                 [] [] [intPrimTy] integerTyCon
418 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_BASE SLIT("J#")
419                 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
420
421
422 isIntegerTy :: Type -> Bool
423 isIntegerTy ty
424   = case (splitAlgTyConApp_maybe ty) of
425         Just (tycon, [], _) -> getUnique tycon == integerTyConKey
426         _                   -> False
427 \end{code}
428
429
430 %************************************************************************
431 %*                                                                      *
432 \subsection[TysWiredIn-ext-type]{External types}
433 %*                                                                      *
434 %************************************************************************
435
436 The compiler's foreign function interface supports the passing of a
437 restricted set of types as arguments and results (the restricting factor
438 being the )
439
440 \begin{code}
441 isFFIArgumentTy :: Type -> Bool
442 isFFIArgumentTy ty =
443   (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
444   case (splitAlgTyConApp_maybe ty) of
445     Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
446     _                  -> False
447
448 -- types that can be passed as arguments to "foreign" functions
449 primArgTyConKeys 
450   = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
451     , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
452     , floatTyConKey, doubleTyConKey
453     , addrTyConKey, charTyConKey, foreignObjTyConKey
454     , stablePtrTyConKey
455     , byteArrayTyConKey, mutableByteArrayTyConKey
456     ]
457
458 -- types that can be passed from the outside world into Haskell.
459 -- excludes (mutable) byteArrays.
460 isFFIExternalTy :: Type -> Bool
461 isFFIExternalTy ty = 
462   (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
463   case (splitAlgTyConApp_maybe ty) of
464     Just (tycon, _, _) -> 
465        let 
466         u_tycon = getUnique tycon
467        in  
468        (u_tycon `elem` primArgTyConKeys) &&
469        not (u_tycon `elem` notLegalExternalTyCons)
470     _                  -> False
471
472
473 isFFIResultTy :: Type -> Bool
474 isFFIResultTy ty =
475    not (isUnLiftedType ty) &&
476    case (splitAlgTyConApp_maybe ty) of
477     Just (tycon, _, _) -> 
478         let
479          u_tycon = getUnique tycon
480         in
481         (u_tycon == getUnique unitTyCon) ||
482         ((u_tycon `elem` primArgTyConKeys) && 
483          not (u_tycon `elem` notLegalExternalTyCons))
484     _                  -> False
485
486 -- it's illegal to return foreign objects and (mutable)
487 -- bytearrays from a _ccall_ / foreign declaration
488 -- (or be passed them as arguments in foreign exported functions).
489 notLegalExternalTyCons =
490   [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
491     
492 \end{code}
493
494 %************************************************************************
495 %*                                                                      *
496 \subsection[TysWiredIn-Bool]{The @Bool@ type}
497 %*                                                                      *
498 %************************************************************************
499
500 An ordinary enumeration type, but deeply wired in.  There are no
501 magical operations on @Bool@ (just the regular Prelude code).
502
503 {\em BEGIN IDLE SPECULATION BY SIMON}
504
505 This is not the only way to encode @Bool@.  A more obvious coding makes
506 @Bool@ just a boxed up version of @Bool#@, like this:
507 \begin{verbatim}
508 type Bool# = Int#
509 data Bool = MkBool Bool#
510 \end{verbatim}
511
512 Unfortunately, this doesn't correspond to what the Report says @Bool@
513 looks like!  Furthermore, we get slightly less efficient code (I
514 think) with this coding. @gtInt@ would look like this:
515
516 \begin{verbatim}
517 gtInt :: Int -> Int -> Bool
518 gtInt x y = case x of I# x# ->
519             case y of I# y# ->
520             case (gtIntPrim x# y#) of
521                 b# -> MkBool b#
522 \end{verbatim}
523
524 Notice that the result of the @gtIntPrim@ comparison has to be turned
525 into an integer (here called @b#@), and returned in a @MkBool@ box.
526
527 The @if@ expression would compile to this:
528 \begin{verbatim}
529 case (gtInt x y) of
530   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
531 \end{verbatim}
532
533 I think this code is a little less efficient than the previous code,
534 but I'm not certain.  At all events, corresponding with the Report is
535 important.  The interesting thing is that the language is expressive
536 enough to describe more than one alternative; and that a type doesn't
537 necessarily need to be a straightforwardly boxed version of its
538 primitive counterpart.
539
540 {\em END IDLE SPECULATION BY SIMON}
541
542 \begin{code}
543 boolTy = mkTyConTy boolTyCon
544
545 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey 
546                     pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
547
548 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
549 trueDataCon  = pcDataCon trueDataConKey  pREL_BASE SLIT("True")  [] [] [] boolTyCon
550 \end{code}
551
552 %************************************************************************
553 %*                                                                      *
554 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
555 %*                                                                      *
556 %************************************************************************
557
558 Special syntax, deeply wired in, but otherwise an ordinary algebraic
559 data types:
560 \begin{verbatim}
561 data [] a = [] | a : (List a)
562 data () = ()
563 data (,) a b = (,,) a b
564 ...
565 \end{verbatim}
566
567 \begin{code}
568 mkListTy :: Type -> Type
569 mkListTy ty = mkTyConApp listTyCon [ty]
570
571 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
572
573 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]") 
574                         alpha_tyvar [nilDataCon, consDataCon]
575
576 nilDataCon  = pcDataCon nilDataConKey  pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
577 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
578                 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
579 -- Interesting: polymorphic recursion would help here.
580 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
581 -- gets the over-specific type (Type -> Type)
582 \end{code}
583
584 %************************************************************************
585 %*                                                                      *
586 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
587 %*                                                                      *
588 %************************************************************************
589
590 The tuple types are definitely magic, because they form an infinite
591 family.
592
593 \begin{itemize}
594 \item
595 They have a special family of type constructors, of type @TyCon@
596 These contain the tycon arity, but don't require a Unique.
597
598 \item
599 They have a special family of constructors, of type
600 @Id@. Again these contain their arity but don't need a Unique.
601
602 \item
603 There should be a magic way of generating the info tables and
604 entry code for all tuples.
605
606 But at the moment we just compile a Haskell source
607 file\srcloc{lib/prelude/...} containing declarations like:
608 \begin{verbatim}
609 data Tuple0             = Tup0
610 data Tuple2  a b        = Tup2  a b
611 data Tuple3  a b c      = Tup3  a b c
612 data Tuple4  a b c d    = Tup4  a b c d
613 ...
614 \end{verbatim}
615 The print-names associated with the magic @Id@s for tuple constructors
616 ``just happen'' to be the same as those generated by these
617 declarations.
618
619 \item
620 The instance environment should have a magic way to know
621 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
622 so on. \ToDo{Not implemented yet.}
623
624 \item
625 There should also be a way to generate the appropriate code for each
626 of these instances, but (like the info tables and entry code) it is
627 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
628 \end{itemize}
629
630 \begin{code}
631 mkTupleTy :: Int -> [Type] -> Type
632 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
633
634 mkUnboxedTupleTy :: Int -> [Type] -> Type
635 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
636
637 unitTy    = mkTupleTy 0 []
638 \end{code}