[project @ 2000-04-05 16:25:51 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, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
90                           mkAlgTyCon, mkSynTyCon, mkTupleTyCon, isUnLiftedTyCon
91                         )
92 import BasicTypes       ( Arity, NewOrData(..), RecFlag(..) )
93 import Type             ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys, 
94                           mkArrowKinds, boxedTypeKind, unboxedTypeKind,
95                           mkFunTy, mkFunTys,
96                           splitTyConApp_maybe, repType,
97                           TauType, ClassContext )
98 import PrimRep          ( PrimRep(..) )
99 import Unique
100 import CmdLineOpts      ( opt_GlasgowExts )
101 import Util             ( assoc )
102 import Panic            ( panic )
103 import Array
104
105 alpha_tyvar       = [alphaTyVar]
106 alpha_ty          = [alphaTy]
107 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
108
109 pcRecDataTyCon, pcNonRecDataTyCon
110         :: Unique{-TyConKey-} -> Module -> FAST_STRING
111         -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
112
113 pcRecDataTyCon    = pcTyCon DataTyCon Recursive
114 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
115
116 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
117   = tycon
118   where
119     tycon = mkAlgTyCon name kind 
120                 tyvars 
121                 []              -- No context
122                 argvrcs
123                 cons
124                 []              -- No derivings
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 %*                                                                      *
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_str tycon
193         tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
194
195         tuple_con = pcDataCon dc_uniq mod 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         mod       = mkPrelModule mod_name
202
203 unitTyCon     = tupleTyCon 0
204 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
205
206 pairTyCon = tupleTyCon 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_str tycon
238         tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
239
240         tuple_con = pcDataCon dc_uniq mod 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         mod       = mkPrelModule mod_name
247
248 unboxedPairTyCon   = unboxedTupleTyCon 2
249 unboxedPairDataCon = unboxedTupleCon 2
250 \end{code}
251
252 %************************************************************************
253 %*                                                                      *
254 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
255 %*                                                                      *
256 %************************************************************************
257
258 \begin{code}
259 -- The Void type is represented as a data type with no constructors
260 -- It's a built in type (i.e. there's no way to define it in Haskell;
261 --      the nearest would be
262 --
263 --              data Void =             -- No constructors!
264 --
265 -- ) It's boxed; there is only one value of this
266 -- type, namely "void", whose semantics is just bottom.
267 --
268 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
269 -- voidTy using ().
270 voidTy = unitTy
271 \end{code}
272
273
274 \begin{code}
275 charTy = mkTyConTy charTyCon
276
277 charTyCon = pcNonRecDataTyCon charTyConKey  pREL_BASE  SLIT("Char") [] [] [charDataCon]
278 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
279
280 stringTy = mkListTy charTy -- convenience only
281 \end{code}
282
283 \begin{code}
284 intTy = mkTyConTy intTyCon 
285
286 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
287 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
288
289 isIntTy :: Type -> Bool
290 isIntTy = isTyCon intTyConKey
291 \end{code}
292
293 \begin{code}
294
295 wordTy = mkTyConTy wordTyCon
296
297 wordTyCon = pcNonRecDataTyCon wordTyConKey   pREL_ADDR SLIT("Word") [] [] [wordDataCon]
298 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
299 \end{code}
300
301 \begin{code}
302 addrTy = mkTyConTy addrTyCon
303
304 addrTyCon = pcNonRecDataTyCon addrTyConKey   pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
305 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
306
307 isAddrTy :: Type -> Bool
308 isAddrTy = isTyCon addrTyConKey
309 \end{code}
310
311 \begin{code}
312 floatTy = mkTyConTy floatTyCon
313
314 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
315 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
316
317 isFloatTy :: Type -> Bool
318 isFloatTy = isTyCon floatTyConKey
319 \end{code}
320
321 \begin{code}
322 doubleTy = mkTyConTy doubleTyCon
323
324 isDoubleTy :: Type -> Bool
325 isDoubleTy = isTyCon doubleTyConKey
326
327 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
328 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
329 \end{code}
330
331 \begin{code}
332 stablePtrTyCon
333   = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
334         alpha_tyvar [(True,False)] [stablePtrDataCon]
335   where
336     stablePtrDataCon
337       = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
338             alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
339 \end{code}
340
341 \begin{code}
342 foreignObjTyCon
343   = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
344         [] [] [foreignObjDataCon]
345   where
346     foreignObjDataCon
347       = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
348             [] [] [foreignObjPrimTy] foreignObjTyCon
349
350 isForeignObjTy :: Type -> Bool
351 isForeignObjTy = isTyCon foreignObjTyConKey
352 \end{code}
353
354 %************************************************************************
355 %*                                                                      *
356 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
357 %*                                                                      *
358 %************************************************************************
359
360 @Integer@ and its pals are not really primitive.  @Integer@ itself, first:
361 \begin{code}
362 integerTy :: Type
363 integerTy = mkTyConTy integerTyCon
364
365 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
366                    [] [] [smallIntegerDataCon, largeIntegerDataCon]
367
368 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
369                 [] [] [intPrimTy] integerTyCon
370 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
371                 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
372
373
374 isIntegerTy :: Type -> Bool
375 isIntegerTy = isTyCon integerTyConKey
376 \end{code}
377
378
379 %************************************************************************
380 %*                                                                      *
381 \subsection[TysWiredIn-ext-type]{External types}
382 %*                                                                      *
383 %************************************************************************
384
385 The compiler's foreign function interface supports the passing of a
386 restricted set of types as arguments and results (the restricting factor
387 being the )
388
389 \begin{code}
390 isFFIArgumentTy :: Bool -> Type -> Bool
391 -- Checks for valid argument type for a 'foreign import'
392 isFFIArgumentTy is_safe ty = checkTyCon (legalOutgoingTyCon is_safe) ty
393
394 isFFIExternalTy :: Type -> Bool
395 -- Types that are allowed as arguments of a 'foreign export'
396 isFFIExternalTy ty = checkTyCon legalIncomingTyCon ty
397
398 isFFIResultTy :: Type -> Bool
399 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
400 -- Maybe we should distinguish between import and export, but 
401 -- here we just choose the more restrictive 'incoming' predicate
402 -- But we allow () as well
403 isFFIResultTy ty = checkTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
404
405 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
406 checkTyCon check_tc ty = case splitTyConApp_maybe (repType ty) of
407                                 Just (tycon, _) -> check_tc tycon
408                                 Nothing         -> False
409
410 isTyCon :: Unique -> Type -> Bool
411 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
412 \end{code}
413
414 ----------------------------------------------
415 These chaps do the work; they are not exported
416 ----------------------------------------------
417
418 \begin{code}
419 legalIncomingTyCon :: TyCon -> Bool
420 -- It's illegal to return foreign objects and (mutable)
421 -- bytearrays from a _ccall_ / foreign declaration
422 -- (or be passed them as arguments in foreign exported functions).
423 legalIncomingTyCon tc
424   | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ] 
425   = False
426   | otherwise
427   = marshalableTyCon tc
428
429 legalOutgoingTyCon :: Bool -> TyCon -> Bool
430 -- Checks validity of types going from Haskell -> external world
431 -- The boolean is true for a 'safe' call (when we don't want to
432 -- pass Haskell pointers to the world)
433 legalOutgoingTyCon be_safe tc
434   | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
435   = False
436   | otherwise
437   = marshalableTyCon tc
438
439 marshalableTyCon tc
440   =  (opt_GlasgowExts && isUnLiftedTyCon tc)
441   || getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
442                          , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
443                          , floatTyConKey, doubleTyConKey
444                          , addrTyConKey, charTyConKey, foreignObjTyConKey
445                          , stablePtrTyConKey
446                          , byteArrayTyConKey, mutableByteArrayTyConKey
447                          , boolTyConKey
448                          ]
449 \end{code}
450
451
452 %************************************************************************
453 %*                                                                      *
454 \subsection[TysWiredIn-Bool]{The @Bool@ type}
455 %*                                                                      *
456 %************************************************************************
457
458 An ordinary enumeration type, but deeply wired in.  There are no
459 magical operations on @Bool@ (just the regular Prelude code).
460
461 {\em BEGIN IDLE SPECULATION BY SIMON}
462
463 This is not the only way to encode @Bool@.  A more obvious coding makes
464 @Bool@ just a boxed up version of @Bool#@, like this:
465 \begin{verbatim}
466 type Bool# = Int#
467 data Bool = MkBool Bool#
468 \end{verbatim}
469
470 Unfortunately, this doesn't correspond to what the Report says @Bool@
471 looks like!  Furthermore, we get slightly less efficient code (I
472 think) with this coding. @gtInt@ would look like this:
473
474 \begin{verbatim}
475 gtInt :: Int -> Int -> Bool
476 gtInt x y = case x of I# x# ->
477             case y of I# y# ->
478             case (gtIntPrim x# y#) of
479                 b# -> MkBool b#
480 \end{verbatim}
481
482 Notice that the result of the @gtIntPrim@ comparison has to be turned
483 into an integer (here called @b#@), and returned in a @MkBool@ box.
484
485 The @if@ expression would compile to this:
486 \begin{verbatim}
487 case (gtInt x y) of
488   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
489 \end{verbatim}
490
491 I think this code is a little less efficient than the previous code,
492 but I'm not certain.  At all events, corresponding with the Report is
493 important.  The interesting thing is that the language is expressive
494 enough to describe more than one alternative; and that a type doesn't
495 necessarily need to be a straightforwardly boxed version of its
496 primitive counterpart.
497
498 {\em END IDLE SPECULATION BY SIMON}
499
500 \begin{code}
501 boolTy = mkTyConTy boolTyCon
502
503 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey 
504                     pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
505
506 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
507 trueDataCon  = pcDataCon trueDataConKey  pREL_BASE SLIT("True")  [] [] [] boolTyCon
508
509 falseDataConId = dataConId falseDataCon
510 trueDataConId  = dataConId trueDataCon
511 \end{code}
512
513 %************************************************************************
514 %*                                                                      *
515 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
516 %*                                                                      *
517 %************************************************************************
518
519 Special syntax, deeply wired in, but otherwise an ordinary algebraic
520 data types:
521 \begin{verbatim}
522 data [] a = [] | a : (List a)
523 data () = ()
524 data (,) a b = (,,) a b
525 ...
526 \end{verbatim}
527
528 \begin{code}
529 mkListTy :: Type -> Type
530 mkListTy ty = mkTyConApp listTyCon [ty]
531
532 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
533
534 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]") 
535                         alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
536
537 nilDataCon  = pcDataCon nilDataConKey  pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
538 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
539                 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
540 -- Interesting: polymorphic recursion would help here.
541 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
542 -- gets the over-specific type (Type -> Type)
543 \end{code}
544
545 %************************************************************************
546 %*                                                                      *
547 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
548 %*                                                                      *
549 %************************************************************************
550
551 The tuple types are definitely magic, because they form an infinite
552 family.
553
554 \begin{itemize}
555 \item
556 They have a special family of type constructors, of type @TyCon@
557 These contain the tycon arity, but don't require a Unique.
558
559 \item
560 They have a special family of constructors, of type
561 @Id@. Again these contain their arity but don't need a Unique.
562
563 \item
564 There should be a magic way of generating the info tables and
565 entry code for all tuples.
566
567 But at the moment we just compile a Haskell source
568 file\srcloc{lib/prelude/...} containing declarations like:
569 \begin{verbatim}
570 data Tuple0             = Tup0
571 data Tuple2  a b        = Tup2  a b
572 data Tuple3  a b c      = Tup3  a b c
573 data Tuple4  a b c d    = Tup4  a b c d
574 ...
575 \end{verbatim}
576 The print-names associated with the magic @Id@s for tuple constructors
577 ``just happen'' to be the same as those generated by these
578 declarations.
579
580 \item
581 The instance environment should have a magic way to know
582 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
583 so on. \ToDo{Not implemented yet.}
584
585 \item
586 There should also be a way to generate the appropriate code for each
587 of these instances, but (like the info tables and entry code) it is
588 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
589 \end{itemize}
590
591 \begin{code}
592 mkTupleTy :: Int -> [Type] -> Type
593 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
594
595 mkUnboxedTupleTy :: Int -> [Type] -> Type
596 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
597
598 unitTy    = mkTupleTy 0 []
599 \end{code}