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