[project @ 2000-03-23 17:45:17 by simonpj]
[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, falseDataConId,
28         floatDataCon,
29         floatTy,
30         isFloatTy,
31         floatTyCon,
32
33         intDataCon,
34         intTy,
35         intTyCon,
36         isIntTy,
37
38         integerTy,
39         integerTyCon,
40         smallIntegerDataCon,
41         largeIntegerDataCon,
42         isIntegerTy,
43
44         listTyCon,
45
46         mkListTy,
47         nilDataCon,
48
49         -- tuples
50         mkTupleTy,
51         tupleTyCon, tupleCon, unitTyCon, unitDataConId, pairTyCon, 
52
53         -- unboxed tuples
54         mkUnboxedTupleTy,
55         unboxedTupleTyCon, unboxedTupleCon, 
56         unboxedPairTyCon, unboxedPairDataCon,
57
58         stablePtrTyCon,
59         stringTy,
60         trueDataCon, trueDataConId,
61         unitTy,
62         voidTy,
63         wordDataCon,
64         wordTy,
65         wordTyCon,
66
67         isFFIArgumentTy,  -- :: Bool -> Type -> Bool
68         isFFIResultTy,    -- :: Type -> Bool
69         isFFIExternalTy,  -- :: Type -> Bool
70         isAddrTy,         -- :: Type -> Bool
71         isForeignObjTy    -- :: Type -> Bool
72
73     ) where
74
75 #include "HsVersions.h"
76
77 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
78
79 -- friends:
80 import PrelMods
81 import TysPrim
82
83 -- others:
84 import Constants        ( mAX_TUPLE_SIZE )
85 import Module           ( Module, mkPrelModule )
86 import Name             ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, mkWorkerOcc, dataName )
87 import DataCon          ( DataCon, StrictnessMark(..),  mkDataCon, dataConId )
88 import Var              ( TyVar, tyVarKind )
89 import TyCon            ( TyCon, ArgVrcs, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
90 import BasicTypes       ( Arity, NewOrData(..), RecFlag(..) )
91 import Type             ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys, 
92                           mkArrowKinds, boxedTypeKind, unboxedTypeKind,
93                           mkFunTy, mkFunTys, isUnLiftedType,
94                           splitTyConApp_maybe, splitAlgTyConApp_maybe,
95                           TauType, ClassContext )
96 import PrimRep          ( PrimRep(..) )
97 import Unique
98 import CmdLineOpts      ( opt_GlasgowExts )
99 import Util             ( assoc )
100 import Panic            ( panic )
101 import Array
102
103 alpha_tyvar       = [alphaTyVar]
104 alpha_ty          = [alphaTy]
105 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
106
107 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
108         :: Unique{-TyConKey-} -> Module -> FAST_STRING
109         -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
110
111 pcRecDataTyCon    = pcTyCon DataType Recursive
112 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
113 pcNonRecNewTyCon  = pcTyCon NewType  NonRecursive
114
115 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
116   = tycon
117   where
118     tycon = mkAlgTyCon name kind 
119                 tyvars 
120                 []              -- No context
121                 argvrcs
122                 cons
123                 []              -- No derivings
124                 Nothing         -- Not a dictionary
125                 new_or_data
126                 is_rec
127
128     name = mkWiredInTyConName key mod str tycon
129     kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
130
131 pcSynTyCon key mod str kind arity tyvars expansion argvrcs  -- this fun never used!
132   = tycon
133   where
134     tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
135     name  = mkWiredInTyConName key mod str tycon
136
137 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
138           -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
139 -- The unique is the first of two free uniques;
140 -- the first is used for the datacon itself and the worker; 
141 -- the second is used for the wrapper.
142 pcDataCon wrap_key mod str tyvars context arg_tys tycon
143   = data_con
144   where
145     data_con = mkDataCon wrap_name 
146                 [ NotMarkedStrict | a <- arg_tys ]
147                 [ {- no labelled fields -} ]
148                 tyvars context [] [] arg_tys tycon work_id wrap_id
149
150     work_occ  = mkWorkerOcc wrap_occ
151     work_key  = incrUnique wrap_key
152     work_name = mkWiredInIdName work_key mod work_occ work_id
153     work_id   = mkDataConId work_name data_con
154     
155     wrap_occ  = mkSrcOccFS dataName str
156     wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
157     wrap_id   = mkDataConWrapId 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_str tycon
192         tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
193
194         tuple_con = pcDataCon dc_uniq mod 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         mod       = mkPrelModule mod_name
201
202 unitTyCon = tupleTyCon 0
203 pairTyCon = tupleTyCon 2
204
205 unitDataConId = dataConId (tupleCon 0)
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_str tycon
237         tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
238
239         tuple_con = pcDataCon dc_uniq mod 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         mod       = mkPrelModule mod_name
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 \end{code}
294
295 \begin{code}
296
297 wordTy = mkTyConTy wordTyCon
298
299 wordTyCon = pcNonRecDataTyCon wordTyConKey   pREL_ADDR SLIT("Word") [] [] [wordDataCon]
300 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
301 \end{code}
302
303 \begin{code}
304 addrTy = mkTyConTy addrTyCon
305
306 addrTyCon = pcNonRecDataTyCon addrTyConKey   pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
307 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
308
309 isAddrTy :: Type -> Bool
310 isAddrTy ty
311   = case (splitAlgTyConApp_maybe ty) of
312         Just (tycon, [], _) -> getUnique tycon == addrTyConKey
313         _                   -> False
314
315 \end{code}
316
317 \begin{code}
318 floatTy = mkTyConTy floatTyCon
319
320 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
321 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
322
323 isFloatTy :: Type -> Bool
324 isFloatTy ty
325   = case (splitAlgTyConApp_maybe ty) of
326         Just (tycon, [], _) -> getUnique tycon == floatTyConKey
327         _                   -> False
328
329 \end{code}
330
331 \begin{code}
332 doubleTy = mkTyConTy doubleTyCon
333
334 isDoubleTy :: Type -> Bool
335 isDoubleTy ty
336   = case (splitAlgTyConApp_maybe ty) of
337         Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
338         _                   -> False
339
340 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
341 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
342 \end{code}
343
344 \begin{code}
345 stablePtrTyCon
346   = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
347         alpha_tyvar [(True,False)] [stablePtrDataCon]
348   where
349     stablePtrDataCon
350       = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
351             alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
352 \end{code}
353
354 \begin{code}
355 foreignObjTyCon
356   = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
357         [] [] [foreignObjDataCon]
358   where
359     foreignObjDataCon
360       = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
361             [] [] [foreignObjPrimTy] foreignObjTyCon
362 \end{code}
363
364 %************************************************************************
365 %*                                                                      *
366 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
367 %*                                                                      *
368 %************************************************************************
369
370 @Integer@ and its pals are not really primitive.  @Integer@ itself, first:
371 \begin{code}
372 integerTy :: Type
373 integerTy = mkTyConTy integerTyCon
374
375 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
376                    [] [] [smallIntegerDataCon, largeIntegerDataCon]
377
378 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
379                 [] [] [intPrimTy] integerTyCon
380 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
381                 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
382
383
384 isIntegerTy :: Type -> Bool
385 isIntegerTy ty
386   = case (splitAlgTyConApp_maybe ty) of
387         Just (tycon, [], _) -> getUnique tycon == integerTyConKey
388         _                   -> False
389 \end{code}
390
391
392 %************************************************************************
393 %*                                                                      *
394 \subsection[TysWiredIn-ext-type]{External types}
395 %*                                                                      *
396 %************************************************************************
397
398 The compiler's foreign function interface supports the passing of a
399 restricted set of types as arguments and results (the restricting factor
400 being the )
401
402 \begin{code}
403 isFFIArgumentTy :: Bool -> Type -> Bool
404 isFFIArgumentTy forASafeCall ty =
405   (opt_GlasgowExts && isUnLiftedType ty) ||
406   case (splitAlgTyConApp_maybe ty) of
407     Just (tycon, _, _) -> 
408                 let
409                  u = getUnique tycon
410                 in
411                 u `elem` primArgTyConKeys &&   -- it has a suitable prim type, and
412                 (not forASafeCall || not ( u `elem` notSafeExternalTyCons)) -- it is safe to pass out.
413     _                  -> False
414
415 -- types that can be passed as arguments to "foreign" functions
416 primArgTyConKeys 
417   = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
418     , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
419     , floatTyConKey, doubleTyConKey
420     , addrTyConKey, charTyConKey, foreignObjTyConKey
421     , stablePtrTyConKey
422     , byteArrayTyConKey, mutableByteArrayTyConKey
423     ]
424
425 -- types that can be passed from the outside world into Haskell.
426 -- excludes (mutable) byteArrays.
427 isFFIExternalTy :: Type -> Bool
428 isFFIExternalTy ty = 
429   (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
430   case (splitAlgTyConApp_maybe ty) of
431     Just (tycon, _, _) -> 
432        let 
433         u_tycon = getUnique tycon
434        in  
435        (u_tycon `elem` primArgTyConKeys) &&
436        not (u_tycon `elem` notLegalExternalTyCons)
437     _                  -> False
438
439
440 isFFIResultTy :: Type -> Bool
441 isFFIResultTy ty =
442    not (isUnLiftedType ty) &&
443    case (splitAlgTyConApp_maybe ty) of
444     Just (tycon, _, _) -> 
445         let
446          u_tycon = getUnique tycon
447         in
448         (u_tycon == getUnique unitTyCon) ||
449         ((u_tycon `elem` primArgTyConKeys) && 
450          not (u_tycon `elem` notLegalExternalTyCons))
451     _                  -> False
452
453 -- it's illegal to return foreign objects and (mutable)
454 -- bytearrays from a _ccall_ / foreign declaration
455 -- (or be passed them as arguments in foreign exported functions).
456 notLegalExternalTyCons =
457   [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
458
459 -- it's really unsafe to pass out references to objects in the heap,
460 -- so for safe call-outs we simply disallow it.
461 notSafeExternalTyCons =
462   [ byteArrayTyConKey, mutableByteArrayTyConKey ]
463
464
465 isForeignObjTy :: Type -> Bool
466 isForeignObjTy ty =
467   case (splitAlgTyConApp_maybe ty) of
468     Just (tycon, _, _) -> (getUnique tycon) == foreignObjTyConKey
469     _                  -> False
470     
471 \end{code}
472
473 %************************************************************************
474 %*                                                                      *
475 \subsection[TysWiredIn-Bool]{The @Bool@ type}
476 %*                                                                      *
477 %************************************************************************
478
479 An ordinary enumeration type, but deeply wired in.  There are no
480 magical operations on @Bool@ (just the regular Prelude code).
481
482 {\em BEGIN IDLE SPECULATION BY SIMON}
483
484 This is not the only way to encode @Bool@.  A more obvious coding makes
485 @Bool@ just a boxed up version of @Bool#@, like this:
486 \begin{verbatim}
487 type Bool# = Int#
488 data Bool = MkBool Bool#
489 \end{verbatim}
490
491 Unfortunately, this doesn't correspond to what the Report says @Bool@
492 looks like!  Furthermore, we get slightly less efficient code (I
493 think) with this coding. @gtInt@ would look like this:
494
495 \begin{verbatim}
496 gtInt :: Int -> Int -> Bool
497 gtInt x y = case x of I# x# ->
498             case y of I# y# ->
499             case (gtIntPrim x# y#) of
500                 b# -> MkBool b#
501 \end{verbatim}
502
503 Notice that the result of the @gtIntPrim@ comparison has to be turned
504 into an integer (here called @b#@), and returned in a @MkBool@ box.
505
506 The @if@ expression would compile to this:
507 \begin{verbatim}
508 case (gtInt x y) of
509   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
510 \end{verbatim}
511
512 I think this code is a little less efficient than the previous code,
513 but I'm not certain.  At all events, corresponding with the Report is
514 important.  The interesting thing is that the language is expressive
515 enough to describe more than one alternative; and that a type doesn't
516 necessarily need to be a straightforwardly boxed version of its
517 primitive counterpart.
518
519 {\em END IDLE SPECULATION BY SIMON}
520
521 \begin{code}
522 boolTy = mkTyConTy boolTyCon
523
524 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey 
525                     pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
526
527 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
528 trueDataCon  = pcDataCon trueDataConKey  pREL_BASE SLIT("True")  [] [] [] boolTyCon
529
530 falseDataConId = dataConId falseDataCon
531 trueDataConId  = dataConId trueDataCon
532 \end{code}
533
534 %************************************************************************
535 %*                                                                      *
536 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
537 %*                                                                      *
538 %************************************************************************
539
540 Special syntax, deeply wired in, but otherwise an ordinary algebraic
541 data types:
542 \begin{verbatim}
543 data [] a = [] | a : (List a)
544 data () = ()
545 data (,) a b = (,,) a b
546 ...
547 \end{verbatim}
548
549 \begin{code}
550 mkListTy :: Type -> Type
551 mkListTy ty = mkTyConApp listTyCon [ty]
552
553 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
554
555 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]") 
556                         alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
557
558 nilDataCon  = pcDataCon nilDataConKey  pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
559 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
560                 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
561 -- Interesting: polymorphic recursion would help here.
562 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
563 -- gets the over-specific type (Type -> Type)
564 \end{code}
565
566 %************************************************************************
567 %*                                                                      *
568 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
569 %*                                                                      *
570 %************************************************************************
571
572 The tuple types are definitely magic, because they form an infinite
573 family.
574
575 \begin{itemize}
576 \item
577 They have a special family of type constructors, of type @TyCon@
578 These contain the tycon arity, but don't require a Unique.
579
580 \item
581 They have a special family of constructors, of type
582 @Id@. Again these contain their arity but don't need a Unique.
583
584 \item
585 There should be a magic way of generating the info tables and
586 entry code for all tuples.
587
588 But at the moment we just compile a Haskell source
589 file\srcloc{lib/prelude/...} containing declarations like:
590 \begin{verbatim}
591 data Tuple0             = Tup0
592 data Tuple2  a b        = Tup2  a b
593 data Tuple3  a b c      = Tup3  a b c
594 data Tuple4  a b c d    = Tup4  a b c d
595 ...
596 \end{verbatim}
597 The print-names associated with the magic @Id@s for tuple constructors
598 ``just happen'' to be the same as those generated by these
599 declarations.
600
601 \item
602 The instance environment should have a magic way to know
603 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
604 so on. \ToDo{Not implemented yet.}
605
606 \item
607 There should also be a way to generate the appropriate code for each
608 of these instances, but (like the info tables and entry code) it is
609 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
610 \end{itemize}
611
612 \begin{code}
613 mkTupleTy :: Int -> [Type] -> Type
614 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
615
616 mkUnboxedTupleTy :: Int -> [Type] -> Type
617 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
618
619 unitTy    = mkTupleTy 0 []
620 \end{code}