565f66ea3d27a196d3846364750d10460f4f187d
[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, AlgTyConFlavour(..), 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
108         :: Unique{-TyConKey-} -> Module -> FAST_STRING
109         -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
110
111 pcRecDataTyCon    = pcTyCon DataTyCon Recursive
112 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
113
114 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
115   = tycon
116   where
117     tycon = mkAlgTyCon name kind 
118                 tyvars 
119                 []              -- No context
120                 argvrcs
121                 cons
122                 []              -- No derivings
123                 new_or_data
124                 is_rec
125
126     name = mkWiredInTyConName key mod str tycon
127     kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
128
129 pcSynTyCon key mod str kind arity tyvars expansion argvrcs  -- this fun never used!
130   = tycon
131   where
132     tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
133     name  = mkWiredInTyConName key mod str tycon
134
135 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
136           -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
137 -- The unique is the first of two free uniques;
138 -- the first is used for the datacon itself and the worker; 
139 -- the second is used for the wrapper.
140 pcDataCon wrap_key mod str tyvars context arg_tys tycon
141   = data_con
142   where
143     data_con = mkDataCon wrap_name 
144                 [ NotMarkedStrict | a <- arg_tys ]
145                 [ {- no labelled fields -} ]
146                 tyvars context [] [] arg_tys tycon work_id wrap_id
147
148     work_occ  = mkWorkerOcc wrap_occ
149     work_key  = incrUnique wrap_key
150     work_name = mkWiredInIdName work_key mod work_occ work_id
151     work_id   = mkDataConId work_name data_con
152     
153     wrap_occ  = mkSrcOccFS dataName str
154     wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
155     wrap_id   = mkDataConWrapId data_con
156 \end{code}
157
158
159 %************************************************************************
160 %*                                                                      *
161 \subsection[TysWiredIn-tuples]{The tuple types}
162 %*                                                                      *
163 %************************************************************************
164
165 \begin{code}
166 tupleTyCon :: Arity -> TyCon
167 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i)    -- Build one specially
168              | otherwise          = tupleTyConArr!i
169
170 tupleCon :: Arity -> DataCon
171 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i)      -- Build one specially
172            | otherwise          = tupleConArr!i
173
174 tupleTyCons :: [TyCon]
175 tupleTyCons = elems tupleTyConArr
176
177 tupleTyConArr :: Array Int TyCon
178 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
179
180 tupleConArr :: Array Int DataCon
181 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
182
183 tuples :: [(TyCon,DataCon)]
184 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
185
186 mk_tuple :: Int -> (TyCon,DataCon)
187 mk_tuple arity = (tycon, tuple_con)
188   where
189         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
190         tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
191         tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
192
193         tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
194         tyvars    = take arity alphaTyVars
195         tyvar_tys = mkTyVarTys tyvars
196         (mod_name, name_str) = mkTupNameStr arity
197         tc_uniq   = mkTupleTyConUnique   arity
198         dc_uniq   = mkTupleDataConUnique arity
199         mod       = mkPrelModule mod_name
200
201 unitTyCon = tupleTyCon 0
202 pairTyCon = tupleTyCon 2
203
204 unitDataConId = dataConId (tupleCon 0)
205 \end{code}
206
207 %************************************************************************
208 %*                                                                      *
209 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
210 %*                                                                      *
211 %************************************************************************
212
213 \begin{code}
214 unboxedTupleTyCon :: Arity -> TyCon
215 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
216                     | otherwise          = unboxedTupleTyConArr!i
217
218 unboxedTupleCon :: Arity -> DataCon
219 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
220                   | otherwise          = unboxedTupleConArr!i
221
222 unboxedTupleTyConArr :: Array Int TyCon
223 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
224
225 unboxedTupleConArr :: Array Int DataCon
226 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
227
228 ubx_tuples :: [(TyCon,DataCon)]
229 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
230
231 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
232 mk_unboxed_tuple arity = (tycon, tuple_con)
233   where
234         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
235         tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
236         tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
237
238         tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
239         tyvars    = take arity openAlphaTyVars
240         tyvar_tys = mkTyVarTys tyvars
241         (mod_name, name_str) = mkUbxTupNameStr arity
242         tc_uniq   = mkUbxTupleTyConUnique   arity
243         dc_uniq   = mkUbxTupleDataConUnique arity
244         mod       = mkPrelModule mod_name
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 \end{code}
293
294 \begin{code}
295
296 wordTy = mkTyConTy wordTyCon
297
298 wordTyCon = pcNonRecDataTyCon wordTyConKey   pREL_ADDR SLIT("Word") [] [] [wordDataCon]
299 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
300 \end{code}
301
302 \begin{code}
303 addrTy = mkTyConTy addrTyCon
304
305 addrTyCon = pcNonRecDataTyCon addrTyConKey   pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
306 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
307
308 isAddrTy :: Type -> Bool
309 isAddrTy ty
310   = case (splitAlgTyConApp_maybe ty) of
311         Just (tycon, [], _) -> getUnique tycon == addrTyConKey
312         _                   -> False
313
314 \end{code}
315
316 \begin{code}
317 floatTy = mkTyConTy floatTyCon
318
319 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
320 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
321
322 isFloatTy :: Type -> Bool
323 isFloatTy ty
324   = case (splitAlgTyConApp_maybe ty) of
325         Just (tycon, [], _) -> getUnique tycon == floatTyConKey
326         _                   -> False
327
328 \end{code}
329
330 \begin{code}
331 doubleTy = mkTyConTy doubleTyCon
332
333 isDoubleTy :: Type -> Bool
334 isDoubleTy ty
335   = case (splitAlgTyConApp_maybe ty) of
336         Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
337         _                   -> False
338
339 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
340 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
341 \end{code}
342
343 \begin{code}
344 stablePtrTyCon
345   = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
346         alpha_tyvar [(True,False)] [stablePtrDataCon]
347   where
348     stablePtrDataCon
349       = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
350             alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
351 \end{code}
352
353 \begin{code}
354 foreignObjTyCon
355   = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
356         [] [] [foreignObjDataCon]
357   where
358     foreignObjDataCon
359       = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
360             [] [] [foreignObjPrimTy] foreignObjTyCon
361 \end{code}
362
363 %************************************************************************
364 %*                                                                      *
365 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
366 %*                                                                      *
367 %************************************************************************
368
369 @Integer@ and its pals are not really primitive.  @Integer@ itself, first:
370 \begin{code}
371 integerTy :: Type
372 integerTy = mkTyConTy integerTyCon
373
374 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
375                    [] [] [smallIntegerDataCon, largeIntegerDataCon]
376
377 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
378                 [] [] [intPrimTy] integerTyCon
379 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
380                 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
381
382
383 isIntegerTy :: Type -> Bool
384 isIntegerTy ty
385   = case (splitAlgTyConApp_maybe ty) of
386         Just (tycon, [], _) -> getUnique tycon == integerTyConKey
387         _                   -> False
388 \end{code}
389
390
391 %************************************************************************
392 %*                                                                      *
393 \subsection[TysWiredIn-ext-type]{External types}
394 %*                                                                      *
395 %************************************************************************
396
397 The compiler's foreign function interface supports the passing of a
398 restricted set of types as arguments and results (the restricting factor
399 being the )
400
401 \begin{code}
402 isFFIArgumentTy :: Bool -> Type -> Bool
403 isFFIArgumentTy forASafeCall ty =
404   (opt_GlasgowExts && isUnLiftedType ty) ||
405   case (splitAlgTyConApp_maybe ty) of
406     Just (tycon, _, _) -> 
407                 let
408                  u = getUnique tycon
409                 in
410                 u `elem` primArgTyConKeys &&   -- it has a suitable prim type, and
411                 (not forASafeCall || not ( u `elem` notSafeExternalTyCons)) -- it is safe to pass out.
412     _                  -> False
413
414 -- types that can be passed as arguments to "foreign" functions
415 primArgTyConKeys 
416   = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
417     , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
418     , floatTyConKey, doubleTyConKey
419     , addrTyConKey, charTyConKey, foreignObjTyConKey
420     , stablePtrTyConKey
421     , byteArrayTyConKey, mutableByteArrayTyConKey
422     ]
423
424 -- types that can be passed from the outside world into Haskell.
425 -- excludes (mutable) byteArrays.
426 isFFIExternalTy :: Type -> Bool
427 isFFIExternalTy ty = 
428   (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
429   case (splitAlgTyConApp_maybe ty) of
430     Just (tycon, _, _) -> 
431        let 
432         u_tycon = getUnique tycon
433        in  
434        (u_tycon `elem` primArgTyConKeys) &&
435        not (u_tycon `elem` notLegalExternalTyCons)
436     _                  -> False
437
438
439 isFFIResultTy :: Type -> Bool
440 isFFIResultTy ty =
441    not (isUnLiftedType ty) &&
442    case (splitAlgTyConApp_maybe ty) of
443     Just (tycon, _, _) -> 
444         let
445          u_tycon = getUnique tycon
446         in
447         (u_tycon == getUnique unitTyCon) ||
448         ((u_tycon `elem` primArgTyConKeys) && 
449          not (u_tycon `elem` notLegalExternalTyCons))
450     _                  -> False
451
452 -- it's illegal to return foreign objects and (mutable)
453 -- bytearrays from a _ccall_ / foreign declaration
454 -- (or be passed them as arguments in foreign exported functions).
455 notLegalExternalTyCons =
456   [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
457
458 -- it's really unsafe to pass out references to objects in the heap,
459 -- so for safe call-outs we simply disallow it.
460 notSafeExternalTyCons =
461   [ byteArrayTyConKey, mutableByteArrayTyConKey ]
462
463
464 isForeignObjTy :: Type -> Bool
465 isForeignObjTy ty =
466   case (splitAlgTyConApp_maybe ty) of
467     Just (tycon, _, _) -> (getUnique tycon) == foreignObjTyConKey
468     _                  -> False
469     
470 \end{code}
471
472 %************************************************************************
473 %*                                                                      *
474 \subsection[TysWiredIn-Bool]{The @Bool@ type}
475 %*                                                                      *
476 %************************************************************************
477
478 An ordinary enumeration type, but deeply wired in.  There are no
479 magical operations on @Bool@ (just the regular Prelude code).
480
481 {\em BEGIN IDLE SPECULATION BY SIMON}
482
483 This is not the only way to encode @Bool@.  A more obvious coding makes
484 @Bool@ just a boxed up version of @Bool#@, like this:
485 \begin{verbatim}
486 type Bool# = Int#
487 data Bool = MkBool Bool#
488 \end{verbatim}
489
490 Unfortunately, this doesn't correspond to what the Report says @Bool@
491 looks like!  Furthermore, we get slightly less efficient code (I
492 think) with this coding. @gtInt@ would look like this:
493
494 \begin{verbatim}
495 gtInt :: Int -> Int -> Bool
496 gtInt x y = case x of I# x# ->
497             case y of I# y# ->
498             case (gtIntPrim x# y#) of
499                 b# -> MkBool b#
500 \end{verbatim}
501
502 Notice that the result of the @gtIntPrim@ comparison has to be turned
503 into an integer (here called @b#@), and returned in a @MkBool@ box.
504
505 The @if@ expression would compile to this:
506 \begin{verbatim}
507 case (gtInt x y) of
508   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
509 \end{verbatim}
510
511 I think this code is a little less efficient than the previous code,
512 but I'm not certain.  At all events, corresponding with the Report is
513 important.  The interesting thing is that the language is expressive
514 enough to describe more than one alternative; and that a type doesn't
515 necessarily need to be a straightforwardly boxed version of its
516 primitive counterpart.
517
518 {\em END IDLE SPECULATION BY SIMON}
519
520 \begin{code}
521 boolTy = mkTyConTy boolTyCon
522
523 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey 
524                     pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
525
526 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
527 trueDataCon  = pcDataCon trueDataConKey  pREL_BASE SLIT("True")  [] [] [] boolTyCon
528
529 falseDataConId = dataConId falseDataCon
530 trueDataConId  = dataConId trueDataCon
531 \end{code}
532
533 %************************************************************************
534 %*                                                                      *
535 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
536 %*                                                                      *
537 %************************************************************************
538
539 Special syntax, deeply wired in, but otherwise an ordinary algebraic
540 data types:
541 \begin{verbatim}
542 data [] a = [] | a : (List a)
543 data () = ()
544 data (,) a b = (,,) a b
545 ...
546 \end{verbatim}
547
548 \begin{code}
549 mkListTy :: Type -> Type
550 mkListTy ty = mkTyConApp listTyCon [ty]
551
552 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
553
554 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]") 
555                         alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
556
557 nilDataCon  = pcDataCon nilDataConKey  pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
558 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
559                 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
560 -- Interesting: polymorphic recursion would help here.
561 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
562 -- gets the over-specific type (Type -> Type)
563 \end{code}
564
565 %************************************************************************
566 %*                                                                      *
567 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
568 %*                                                                      *
569 %************************************************************************
570
571 The tuple types are definitely magic, because they form an infinite
572 family.
573
574 \begin{itemize}
575 \item
576 They have a special family of type constructors, of type @TyCon@
577 These contain the tycon arity, but don't require a Unique.
578
579 \item
580 They have a special family of constructors, of type
581 @Id@. Again these contain their arity but don't need a Unique.
582
583 \item
584 There should be a magic way of generating the info tables and
585 entry code for all tuples.
586
587 But at the moment we just compile a Haskell source
588 file\srcloc{lib/prelude/...} containing declarations like:
589 \begin{verbatim}
590 data Tuple0             = Tup0
591 data Tuple2  a b        = Tup2  a b
592 data Tuple3  a b c      = Tup3  a b c
593 data Tuple4  a b c d    = Tup4  a b c d
594 ...
595 \end{verbatim}
596 The print-names associated with the magic @Id@s for tuple constructors
597 ``just happen'' to be the same as those generated by these
598 declarations.
599
600 \item
601 The instance environment should have a magic way to know
602 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
603 so on. \ToDo{Not implemented yet.}
604
605 \item
606 There should also be a way to generate the appropriate code for each
607 of these instances, but (like the info tables and entry code) it is
608 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
609 \end{itemize}
610
611 \begin{code}
612 mkTupleTy :: Int -> [Type] -> Type
613 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
614
615 mkUnboxedTupleTy :: Int -> [Type] -> Type
616 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
617
618 unitTy    = mkTupleTy 0 []
619 \end{code}