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 ( mkWiredInTyConName, mkWiredInIdName, mkTupNameStr,
107 import DataCon ( DataCon, mkDataCon )
108 import Var ( TyVar, tyVarKind )
109 import TyCon ( TyCon, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
110 import BasicTypes ( Module, Arity, NewOrData(..),
111 RecFlag(..), StrictnessMark(..) )
112 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
113 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
114 mkFunTy, mkFunTys, isUnLiftedType,
115 splitTyConApp_maybe, splitAlgTyConApp_maybe,
116 GenType(..), ThetaType, TauType )
117 import PrimRep ( PrimRep(..) )
119 import CmdLineOpts ( opt_GlasgowExts )
120 import Util ( assoc, 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 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.
274 voidTy = mkTyConTy voidTyCon
275 voidTyCon = pcNonRecDataTyCon voidTyConKey pREL_GHC SLIT("Void") [] [{-No data cons-}]
279 charTy = mkTyConTy charTyCon
281 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [charDataCon]
282 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
284 stringTy = mkListTy charTy -- convenience only
288 intTy = mkTyConTy intTyCon
290 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
291 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
293 isIntTy :: GenType flexi -> Bool
295 = case (splitAlgTyConApp_maybe ty) of
296 Just (tycon, [], _) -> getUnique tycon == intTyConKey
299 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
300 inIntRange i = (min_int <= i) && (i <= max_int)
302 max_int, min_int :: Integer
303 max_int = toInteger maxInt
304 min_int = toInteger minInt
306 int8TyCon = pcNonRecDataTyCon int8TyConKey iNT SLIT("Int8") [] [int8DataCon]
308 int8DataCon = pcDataCon int8DataConKey iNT SLIT("I8#") [] [] [intPrimTy] int8TyCon
310 int16TyCon = pcNonRecDataTyCon int16TyConKey iNT SLIT("Int16") [] [int16DataCon]
312 int16DataCon = pcDataCon int16DataConKey iNT SLIT("I16#") [] [] [intPrimTy] int16TyCon
314 int32TyCon = pcNonRecDataTyCon int32TyConKey iNT SLIT("Int32") [] [int32DataCon]
316 int32DataCon = pcDataCon int32DataConKey iNT SLIT("I32#") [] [] [intPrimTy] int32TyCon
318 int64Ty = mkTyConTy int64TyCon
320 int64TyCon = pcNonRecDataTyCon int64TyConKey pREL_ADDR SLIT("Int64") [] [int64DataCon]
321 int64DataCon = pcDataCon int64DataConKey pREL_ADDR SLIT("I64#") [] [] [int64PrimTy] int64TyCon
326 wordTy = mkTyConTy wordTyCon
328 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [wordDataCon]
329 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
331 word8TyCon = pcNonRecDataTyCon word8TyConKey wORD SLIT("Word8") [] [word8DataCon]
333 word8DataCon = pcDataCon word8DataConKey wORD SLIT("W8#") [] [] [wordPrimTy] word8TyCon
335 word16TyCon = pcNonRecDataTyCon word16TyConKey wORD SLIT("Word16") [] [word16DataCon]
337 word16DataCon = pcDataCon word16DataConKey wORD SLIT("W16#") [] [] [wordPrimTy] word16TyCon
339 word32TyCon = pcNonRecDataTyCon word32TyConKey wORD SLIT("Word32") [] [word32DataCon]
341 word32DataCon = pcDataCon word32DataConKey wORD SLIT("W32#") [] [] [wordPrimTy] word32TyCon
343 word64Ty = mkTyConTy word64TyCon
345 word64TyCon = pcNonRecDataTyCon word64TyConKey pREL_ADDR SLIT("Word64") [] [word64DataCon]
346 word64DataCon = pcDataCon word64DataConKey pREL_ADDR SLIT("W64#") [] [] [word64PrimTy] word64TyCon
350 addrTy = mkTyConTy addrTyCon
352 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [addrDataCon]
353 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
355 isAddrTy :: GenType flexi -> Bool
357 = case (splitAlgTyConApp_maybe ty) of
358 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
364 floatTy = mkTyConTy floatTyCon
366 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
367 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
369 isFloatTy :: GenType flexi -> Bool
371 = case (splitAlgTyConApp_maybe ty) of
372 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
378 doubleTy = mkTyConTy doubleTyCon
380 isDoubleTy :: GenType flexi -> Bool
382 = case (splitAlgTyConApp_maybe ty) of
383 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
386 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
387 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
391 mkStateTy ty = mkTyConApp stateTyCon [ty]
392 realWorldStateTy = mkStateTy realWorldTy -- a common use
394 stateTyCon = pcNonRecDataTyCon stateTyConKey pREL_ST SLIT("State") alpha_tyvar [stateDataCon]
396 = pcDataCon stateDataConKey pREL_ST SLIT("S#")
397 alpha_tyvar [] [mkStatePrimTy alphaTy] stateTyCon
402 = pcNonRecDataTyCon stablePtrTyConKey pREL_FOREIGN SLIT("StablePtr")
403 alpha_tyvar [stablePtrDataCon]
406 = pcDataCon stablePtrDataConKey pREL_FOREIGN SLIT("StablePtr")
407 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
412 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
413 [] [foreignObjDataCon]
416 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
417 [] [] [foreignObjPrimTy] foreignObjTyCon
420 %************************************************************************
422 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
424 %************************************************************************
426 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
428 integerTy :: GenType t
429 integerTy = mkTyConTy integerTyCon
431 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [integerDataCon]
433 integerDataCon = pcDataCon integerDataConKey pREL_BASE SLIT("J#")
434 [] [] [intPrimTy, intPrimTy, byteArrayPrimTy] integerTyCon
436 isIntegerTy :: GenType flexi -> Bool
438 = case (splitAlgTyConApp_maybe ty) of
439 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
444 %************************************************************************
446 \subsection[TysWiredIn-ext-type]{External types}
448 %************************************************************************
450 The compiler's foreign function interface supports the passing of a
451 restricted set of types as arguments and results (the restricting factor
455 isFFIArgumentTy :: Type -> Bool
457 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
458 case (splitAlgTyConApp_maybe ty) of
459 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
462 -- types that can be passed as arguments to "foreign" functions
464 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
465 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
466 , floatTyConKey, doubleTyConKey
467 , addrTyConKey, charTyConKey, foreignObjTyConKey
468 , stablePtrTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey
471 -- types that can be passed from the outside world into Haskell.
472 -- excludes (mutable) byteArrays.
473 isFFIExternalTy :: Type -> Bool
475 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
476 case (splitAlgTyConApp_maybe ty) of
477 Just (tycon, _, _) ->
479 u_tycon = getUnique tycon
481 (u_tycon `elem` primArgTyConKeys) &&
482 not (u_tycon `elem` notLegalExternalTyCons)
486 isFFIResultTy :: Type -> Bool
488 not (isUnLiftedType ty) &&
489 case (splitAlgTyConApp_maybe ty) of
490 Just (tycon, _, _) ->
492 u_tycon = getUnique tycon
494 (u_tycon == getUnique unitTyCon) ||
495 ((u_tycon `elem` primArgTyConKeys) &&
496 not (u_tycon `elem` notLegalExternalTyCons))
499 -- it's illegal to return foreign objects and (mutable)
500 -- bytearrays from a _ccall_ / foreign declaration
501 -- (or be passed them as arguments in foreign exported functions).
502 notLegalExternalTyCons =
503 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
507 %************************************************************************
509 \subsection[TysWiredIn-Bool]{The @Bool@ type}
511 %************************************************************************
513 An ordinary enumeration type, but deeply wired in. There are no
514 magical operations on @Bool@ (just the regular Prelude code).
516 {\em BEGIN IDLE SPECULATION BY SIMON}
518 This is not the only way to encode @Bool@. A more obvious coding makes
519 @Bool@ just a boxed up version of @Bool#@, like this:
522 data Bool = MkBool Bool#
525 Unfortunately, this doesn't correspond to what the Report says @Bool@
526 looks like! Furthermore, we get slightly less efficient code (I
527 think) with this coding. @gtInt@ would look like this:
530 gtInt :: Int -> Int -> Bool
531 gtInt x y = case x of I# x# ->
533 case (gtIntPrim x# y#) of
537 Notice that the result of the @gtIntPrim@ comparison has to be turned
538 into an integer (here called @b#@), and returned in a @MkBool@ box.
540 The @if@ expression would compile to this:
543 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
546 I think this code is a little less efficient than the previous code,
547 but I'm not certain. At all events, corresponding with the Report is
548 important. The interesting thing is that the language is expressive
549 enough to describe more than one alternative; and that a type doesn't
550 necessarily need to be a straightforwardly boxed version of its
551 primitive counterpart.
553 {\em END IDLE SPECULATION BY SIMON}
556 boolTy = mkTyConTy boolTyCon
558 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
559 pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
561 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
562 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
565 %************************************************************************
567 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
569 %************************************************************************
571 Special syntax, deeply wired in, but otherwise an ordinary algebraic
574 data [] a = [] | a : (List a)
576 data (,) a b = (,,) a b
581 mkListTy :: GenType t -> GenType t
582 mkListTy ty = mkTyConApp listTyCon [ty]
584 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
586 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
587 alpha_tyvar [nilDataCon, consDataCon]
589 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
590 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
591 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
592 -- Interesting: polymorphic recursion would help here.
593 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
594 -- gets the over-specific type (Type -> Type)
597 %************************************************************************
599 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
601 %************************************************************************
603 The tuple types are definitely magic, because they form an infinite
608 They have a special family of type constructors, of type @TyCon@
609 These contain the tycon arity, but don't require a Unique.
612 They have a special family of constructors, of type
613 @Id@. Again these contain their arity but don't need a Unique.
616 There should be a magic way of generating the info tables and
617 entry code for all tuples.
619 But at the moment we just compile a Haskell source
620 file\srcloc{lib/prelude/...} containing declarations like:
623 data Tuple2 a b = Tup2 a b
624 data Tuple3 a b c = Tup3 a b c
625 data Tuple4 a b c d = Tup4 a b c d
628 The print-names associated with the magic @Id@s for tuple constructors
629 ``just happen'' to be the same as those generated by these
633 The instance environment should have a magic way to know
634 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
635 so on. \ToDo{Not implemented yet.}
638 There should also be a way to generate the appropriate code for each
639 of these instances, but (like the info tables and entry code) it is
640 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
644 mkTupleTy :: Int -> [GenType t] -> GenType t
645 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
647 mkUnboxedTupleTy :: Int -> [GenType t] -> GenType t
648 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
650 unitTy = mkTupleTy 0 []