2 % (c) The GRASP Project, Glasgow University, 1994-1998
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
6 This module is about types that can be defined in Haskell, but which
7 must be wired into the compiler nonetheless.
9 This module tracks the ``state interface'' document, ``GHC prelude:
10 types and operations.''
61 tupleTyCon, tupleCon, unitTyCon, unitDataCon, pairTyCon, pairDataCon,
65 unboxedTupleTyCon, unboxedTupleCon,
66 unboxedPairTyCon, unboxedPairDataCon,
88 isFFIArgumentTy, -- :: Type -> Bool
89 isFFIResultTy, -- :: Type -> Bool
90 isFFIExternalTy, -- :: Type -> Bool
91 isAddrTy, -- :: Type -> Bool
95 #include "HsVersions.h"
97 import {-# SOURCE #-} MkId( mkDataConId )
104 import Constants ( mAX_TUPLE_SIZE )
105 import Name ( Module, varOcc, mkWiredInTyConName, mkWiredInIdName )
106 import DataCon ( DataCon, mkDataCon )
107 import Var ( TyVar, tyVarKind )
108 import TyCon ( TyCon, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
109 import BasicTypes ( Arity, NewOrData(..),
110 RecFlag(..), StrictnessMark(..) )
111 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
112 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
113 mkFunTy, mkFunTys, isUnLiftedType,
114 splitTyConApp_maybe, splitAlgTyConApp_maybe,
116 import PrimRep ( PrimRep(..) )
118 import CmdLineOpts ( opt_GlasgowExts )
119 import Util ( assoc )
120 import Panic ( panic )
123 alpha_tyvar = [alphaTyVar]
125 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
127 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
128 :: Unique{-TyConKey-} -> Module -> FAST_STRING
129 -> [TyVar] -> [DataCon] -> TyCon
131 pcRecDataTyCon = pcTyCon DataType Recursive
132 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
133 pcNonRecNewTyCon = pcTyCon NewType NonRecursive
135 pcTyCon new_or_data is_rec key mod str tyvars cons
138 tycon = mkAlgTyCon name kind
143 Nothing -- Not a dictionary
147 name = mkWiredInTyConName key mod str tycon
148 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
150 pcSynTyCon key mod str kind arity tyvars expansion
153 tycon = mkSynTyCon name kind arity tyvars expansion
154 name = mkWiredInTyConName key mod str tycon
156 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
157 -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
158 pcDataCon key mod str tyvars context arg_tys tycon
161 data_con = mkDataCon name
162 [ NotMarkedStrict | a <- arg_tys ]
163 [ {- no labelled fields -} ]
164 tyvars context [] [] arg_tys tycon id
165 name = mkWiredInIdName key mod (varOcc str) id
166 id = mkDataConId data_con
169 %************************************************************************
171 \subsection[TysWiredIn-tuples]{The tuple types}
173 %************************************************************************
176 tupleTyCon :: Arity -> TyCon
177 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i) -- Build one specially
178 | otherwise = tupleTyConArr!i
180 tupleCon :: Arity -> DataCon
181 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i) -- Build one specially
182 | otherwise = tupleConArr!i
184 tupleTyCons :: [TyCon]
185 tupleTyCons = elems tupleTyConArr
187 tupleTyConArr :: Array Int TyCon
188 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
190 tupleConArr :: Array Int DataCon
191 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
193 tuples :: [(TyCon,DataCon)]
194 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
196 mk_tuple :: Int -> (TyCon,DataCon)
197 mk_tuple arity = (tycon, tuple_con)
199 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
200 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
201 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
203 tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
204 tyvars = take arity alphaTyVars
205 tyvar_tys = mkTyVarTys tyvars
206 (mod_name, name_str) = mkTupNameStr arity
207 tc_uniq = mkTupleTyConUnique arity
208 dc_uniq = mkTupleDataConUnique arity
210 unitTyCon = tupleTyCon 0
211 pairTyCon = tupleTyCon 2
213 unitDataCon = tupleCon 0
214 pairDataCon = tupleCon 2
217 %************************************************************************
219 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
221 %************************************************************************
224 unboxedTupleTyCon :: Arity -> TyCon
225 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
226 | otherwise = unboxedTupleTyConArr!i
228 unboxedTupleCon :: Arity -> DataCon
229 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
230 | otherwise = unboxedTupleConArr!i
232 unboxedTupleTyConArr :: Array Int TyCon
233 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
235 unboxedTupleConArr :: Array Int DataCon
236 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
238 ubx_tuples :: [(TyCon,DataCon)]
239 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
241 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
242 mk_unboxed_tuple arity = (tycon, tuple_con)
244 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
245 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
246 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
248 tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
249 tyvars = take arity openAlphaTyVars
250 tyvar_tys = mkTyVarTys tyvars
251 (mod_name, name_str) = mkUbxTupNameStr arity
252 tc_uniq = mkUbxTupleTyConUnique arity
253 dc_uniq = mkUbxTupleDataConUnique arity
255 unboxedPairTyCon = unboxedTupleTyCon 2
256 unboxedPairDataCon = unboxedTupleCon 2
259 %************************************************************************
261 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
263 %************************************************************************
266 -- The Void type is represented as a data type with no constructors
267 -- It's a built in type (i.e. there's no way to define it in Haskell;
268 -- the nearest would be
270 -- data Void = -- No constructors!
272 -- ) It's boxed; there is only one value of this
273 -- type, namely "void", whose semantics is just bottom.
275 voidTy = mkTyConTy voidTyCon
276 voidTyCon = pcNonRecDataTyCon voidTyConKey pREL_GHC SLIT("Void") [] [{-No data cons-}]
281 charTy = mkTyConTy charTyCon
283 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [charDataCon]
284 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
286 stringTy = mkListTy charTy -- convenience only
290 intTy = mkTyConTy intTyCon
292 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
293 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
295 isIntTy :: Type -> Bool
297 = case (splitAlgTyConApp_maybe ty) of
298 Just (tycon, [], _) -> getUnique tycon == intTyConKey
301 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
302 inIntRange i = (min_int <= i) && (i <= max_int)
304 max_int, min_int :: Integer
305 max_int = toInteger maxInt
306 min_int = toInteger minInt
308 int8TyCon = pcNonRecDataTyCon int8TyConKey iNT SLIT("Int8") [] [int8DataCon]
310 int8DataCon = pcDataCon int8DataConKey iNT SLIT("I8#") [] [] [intPrimTy] int8TyCon
312 int16TyCon = pcNonRecDataTyCon int16TyConKey iNT SLIT("Int16") [] [int16DataCon]
314 int16DataCon = pcDataCon int16DataConKey iNT SLIT("I16#") [] [] [intPrimTy] int16TyCon
316 int32TyCon = pcNonRecDataTyCon int32TyConKey iNT SLIT("Int32") [] [int32DataCon]
318 int32DataCon = pcDataCon int32DataConKey iNT SLIT("I32#") [] [] [intPrimTy] int32TyCon
320 int64Ty = mkTyConTy int64TyCon
322 int64TyCon = pcNonRecDataTyCon int64TyConKey pREL_ADDR SLIT("Int64") [] [int64DataCon]
323 int64DataCon = pcDataCon int64DataConKey pREL_ADDR SLIT("I64#") [] [] [int64PrimTy] int64TyCon
328 wordTy = mkTyConTy wordTyCon
330 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [wordDataCon]
331 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
333 word8TyCon = pcNonRecDataTyCon word8TyConKey wORD SLIT("Word8") [] [word8DataCon]
335 word8DataCon = pcDataCon word8DataConKey wORD SLIT("W8#") [] [] [wordPrimTy] word8TyCon
337 word16TyCon = pcNonRecDataTyCon word16TyConKey wORD SLIT("Word16") [] [word16DataCon]
339 word16DataCon = pcDataCon word16DataConKey wORD SLIT("W16#") [] [] [wordPrimTy] word16TyCon
341 word32TyCon = pcNonRecDataTyCon word32TyConKey wORD SLIT("Word32") [] [word32DataCon]
343 word32DataCon = pcDataCon word32DataConKey wORD SLIT("W32#") [] [] [wordPrimTy] word32TyCon
345 word64Ty = mkTyConTy word64TyCon
347 word64TyCon = pcNonRecDataTyCon word64TyConKey pREL_ADDR SLIT("Word64") [] [word64DataCon]
348 word64DataCon = pcDataCon word64DataConKey pREL_ADDR SLIT("W64#") [] [] [word64PrimTy] word64TyCon
352 addrTy = mkTyConTy addrTyCon
354 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [addrDataCon]
355 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
357 isAddrTy :: Type -> Bool
359 = case (splitAlgTyConApp_maybe ty) of
360 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
366 floatTy = mkTyConTy floatTyCon
368 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
369 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
371 isFloatTy :: Type -> Bool
373 = case (splitAlgTyConApp_maybe ty) of
374 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
380 doubleTy = mkTyConTy doubleTyCon
382 isDoubleTy :: Type -> Bool
384 = case (splitAlgTyConApp_maybe ty) of
385 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
388 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
389 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
393 mkStateTy ty = mkTyConApp stateTyCon [ty]
394 realWorldStateTy = mkStateTy realWorldTy -- a common use
396 stateTyCon = pcNonRecDataTyCon stateTyConKey pREL_ST SLIT("State") alpha_tyvar [stateDataCon]
398 = pcDataCon stateDataConKey pREL_ST SLIT("S#")
399 alpha_tyvar [] [mkStatePrimTy alphaTy] stateTyCon
404 = pcNonRecDataTyCon stablePtrTyConKey pREL_FOREIGN SLIT("StablePtr")
405 alpha_tyvar [stablePtrDataCon]
408 = pcDataCon stablePtrDataConKey pREL_FOREIGN SLIT("StablePtr")
409 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
414 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
415 [] [foreignObjDataCon]
418 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
419 [] [] [foreignObjPrimTy] foreignObjTyCon
422 %************************************************************************
424 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
426 %************************************************************************
428 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
431 integerTy = mkTyConTy integerTyCon
433 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [integerDataCon]
435 integerDataCon = pcDataCon integerDataConKey pREL_BASE SLIT("J#")
436 [] [] [intPrimTy, intPrimTy, byteArrayPrimTy] integerTyCon
438 isIntegerTy :: Type -> Bool
440 = case (splitAlgTyConApp_maybe ty) of
441 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
446 %************************************************************************
448 \subsection[TysWiredIn-ext-type]{External types}
450 %************************************************************************
452 The compiler's foreign function interface supports the passing of a
453 restricted set of types as arguments and results (the restricting factor
457 isFFIArgumentTy :: Type -> Bool
459 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
460 case (splitAlgTyConApp_maybe ty) of
461 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
464 -- types that can be passed as arguments to "foreign" functions
466 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
467 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
468 , floatTyConKey, doubleTyConKey
469 , addrTyConKey, charTyConKey, foreignObjTyConKey
470 , stablePtrTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey
473 -- types that can be passed from the outside world into Haskell.
474 -- excludes (mutable) byteArrays.
475 isFFIExternalTy :: Type -> Bool
477 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
478 case (splitAlgTyConApp_maybe ty) of
479 Just (tycon, _, _) ->
481 u_tycon = getUnique tycon
483 (u_tycon `elem` primArgTyConKeys) &&
484 not (u_tycon `elem` notLegalExternalTyCons)
488 isFFIResultTy :: Type -> Bool
490 not (isUnLiftedType ty) &&
491 case (splitAlgTyConApp_maybe ty) of
492 Just (tycon, _, _) ->
494 u_tycon = getUnique tycon
496 (u_tycon == getUnique unitTyCon) ||
497 ((u_tycon `elem` primArgTyConKeys) &&
498 not (u_tycon `elem` notLegalExternalTyCons))
501 -- it's illegal to return foreign objects and (mutable)
502 -- bytearrays from a _ccall_ / foreign declaration
503 -- (or be passed them as arguments in foreign exported functions).
504 notLegalExternalTyCons =
505 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
509 %************************************************************************
511 \subsection[TysWiredIn-Bool]{The @Bool@ type}
513 %************************************************************************
515 An ordinary enumeration type, but deeply wired in. There are no
516 magical operations on @Bool@ (just the regular Prelude code).
518 {\em BEGIN IDLE SPECULATION BY SIMON}
520 This is not the only way to encode @Bool@. A more obvious coding makes
521 @Bool@ just a boxed up version of @Bool#@, like this:
524 data Bool = MkBool Bool#
527 Unfortunately, this doesn't correspond to what the Report says @Bool@
528 looks like! Furthermore, we get slightly less efficient code (I
529 think) with this coding. @gtInt@ would look like this:
532 gtInt :: Int -> Int -> Bool
533 gtInt x y = case x of I# x# ->
535 case (gtIntPrim x# y#) of
539 Notice that the result of the @gtIntPrim@ comparison has to be turned
540 into an integer (here called @b#@), and returned in a @MkBool@ box.
542 The @if@ expression would compile to this:
545 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
548 I think this code is a little less efficient than the previous code,
549 but I'm not certain. At all events, corresponding with the Report is
550 important. The interesting thing is that the language is expressive
551 enough to describe more than one alternative; and that a type doesn't
552 necessarily need to be a straightforwardly boxed version of its
553 primitive counterpart.
555 {\em END IDLE SPECULATION BY SIMON}
558 boolTy = mkTyConTy boolTyCon
560 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
561 pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
563 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
564 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
567 %************************************************************************
569 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
571 %************************************************************************
573 Special syntax, deeply wired in, but otherwise an ordinary algebraic
576 data [] a = [] | a : (List a)
578 data (,) a b = (,,) a b
583 mkListTy :: Type -> Type
584 mkListTy ty = mkTyConApp listTyCon [ty]
586 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
588 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
589 alpha_tyvar [nilDataCon, consDataCon]
591 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
592 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
593 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
594 -- Interesting: polymorphic recursion would help here.
595 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
596 -- gets the over-specific type (Type -> Type)
599 %************************************************************************
601 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
603 %************************************************************************
605 The tuple types are definitely magic, because they form an infinite
610 They have a special family of type constructors, of type @TyCon@
611 These contain the tycon arity, but don't require a Unique.
614 They have a special family of constructors, of type
615 @Id@. Again these contain their arity but don't need a Unique.
618 There should be a magic way of generating the info tables and
619 entry code for all tuples.
621 But at the moment we just compile a Haskell source
622 file\srcloc{lib/prelude/...} containing declarations like:
625 data Tuple2 a b = Tup2 a b
626 data Tuple3 a b c = Tup3 a b c
627 data Tuple4 a b c d = Tup4 a b c d
630 The print-names associated with the magic @Id@s for tuple constructors
631 ``just happen'' to be the same as those generated by these
635 The instance environment should have a magic way to know
636 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
637 so on. \ToDo{Not implemented yet.}
640 There should also be a way to generate the appropriate code for each
641 of these instances, but (like the info tables and entry code) it is
642 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
646 mkTupleTy :: Int -> [Type] -> Type
647 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
649 mkUnboxedTupleTy :: Int -> [Type] -> Type
650 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
652 unitTy = mkTupleTy 0 []