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.''
58 tupleTyCon, tupleCon, unitTyCon, unitDataCon, pairTyCon, pairDataCon,
62 unboxedTupleTyCon, unboxedTupleCon,
63 unboxedPairTyCon, unboxedPairDataCon,
79 isFFIArgumentTy, -- :: Type -> Bool
80 isFFIResultTy, -- :: Type -> Bool
81 isFFIExternalTy, -- :: Type -> Bool
82 isAddrTy, -- :: Type -> Bool
86 #include "HsVersions.h"
88 import {-# SOURCE #-} MkId( mkDataConId )
95 import Constants ( mAX_TUPLE_SIZE )
96 import Name ( Module, mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, dataName )
97 import DataCon ( DataCon, mkDataCon )
98 import Var ( TyVar, tyVarKind )
99 import TyCon ( TyCon, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
100 import BasicTypes ( Arity, NewOrData(..),
101 RecFlag(..), StrictnessMark(..) )
102 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
103 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
104 mkFunTy, mkFunTys, isUnLiftedType,
105 splitTyConApp_maybe, splitAlgTyConApp_maybe,
107 import PrimRep ( PrimRep(..) )
109 import CmdLineOpts ( opt_GlasgowExts )
110 import Util ( assoc )
111 import Panic ( panic )
114 alpha_tyvar = [alphaTyVar]
116 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
118 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
119 :: Unique{-TyConKey-} -> Module -> FAST_STRING
120 -> [TyVar] -> [DataCon] -> TyCon
122 pcRecDataTyCon = pcTyCon DataType Recursive
123 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
124 pcNonRecNewTyCon = pcTyCon NewType NonRecursive
126 pcTyCon new_or_data is_rec key mod str tyvars cons
129 tycon = mkAlgTyCon name kind
134 Nothing -- Not a dictionary
138 name = mkWiredInTyConName key mod str tycon
139 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
141 pcSynTyCon key mod str kind arity tyvars expansion
144 tycon = mkSynTyCon name kind arity tyvars expansion
145 name = mkWiredInTyConName key mod str tycon
147 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
148 -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
149 pcDataCon key mod str tyvars context arg_tys tycon
152 data_con = mkDataCon name
153 [ NotMarkedStrict | a <- arg_tys ]
154 [ {- no labelled fields -} ]
155 tyvars context [] [] arg_tys tycon id
156 name = mkWiredInIdName key mod (mkSrcOccFS dataName str) id
157 id = mkDataConId data_con
160 %************************************************************************
162 \subsection[TysWiredIn-tuples]{The tuple types}
164 %************************************************************************
167 tupleTyCon :: Arity -> TyCon
168 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i) -- Build one specially
169 | otherwise = tupleTyConArr!i
171 tupleCon :: Arity -> DataCon
172 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i) -- Build one specially
173 | otherwise = tupleConArr!i
175 tupleTyCons :: [TyCon]
176 tupleTyCons = elems tupleTyConArr
178 tupleTyConArr :: Array Int TyCon
179 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
181 tupleConArr :: Array Int DataCon
182 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
184 tuples :: [(TyCon,DataCon)]
185 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
187 mk_tuple :: Int -> (TyCon,DataCon)
188 mk_tuple arity = (tycon, tuple_con)
190 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
191 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
192 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
194 tuple_con = pcDataCon dc_uniq mod_name 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
201 unitTyCon = tupleTyCon 0
202 pairTyCon = tupleTyCon 2
204 unitDataCon = tupleCon 0
205 pairDataCon = tupleCon 2
208 %************************************************************************
210 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
212 %************************************************************************
215 unboxedTupleTyCon :: Arity -> TyCon
216 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
217 | otherwise = unboxedTupleTyConArr!i
219 unboxedTupleCon :: Arity -> DataCon
220 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
221 | otherwise = unboxedTupleConArr!i
223 unboxedTupleTyConArr :: Array Int TyCon
224 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
226 unboxedTupleConArr :: Array Int DataCon
227 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
229 ubx_tuples :: [(TyCon,DataCon)]
230 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
232 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
233 mk_unboxed_tuple arity = (tycon, tuple_con)
235 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
236 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
237 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
239 tuple_con = pcDataCon dc_uniq mod_name 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
246 unboxedPairTyCon = unboxedTupleTyCon 2
247 unboxedPairDataCon = unboxedTupleCon 2
250 %************************************************************************
252 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
254 %************************************************************************
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
261 -- data Void = -- No constructors!
263 -- ) It's boxed; there is only one value of this
264 -- type, namely "void", whose semantics is just bottom.
266 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
273 charTy = mkTyConTy charTyCon
275 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [charDataCon]
276 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
278 stringTy = mkListTy charTy -- convenience only
282 intTy = mkTyConTy intTyCon
284 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
285 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
287 isIntTy :: Type -> Bool
289 = case (splitAlgTyConApp_maybe ty) of
290 Just (tycon, [], _) -> getUnique tycon == intTyConKey
293 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
294 inIntRange i = (min_int <= i) && (i <= max_int)
296 max_int, min_int :: Integer
297 max_int = toInteger maxInt
298 min_int = toInteger minInt
300 int8TyCon = pcNonRecDataTyCon int8TyConKey iNT SLIT("Int8") [] [int8DataCon]
302 int8DataCon = pcDataCon int8DataConKey iNT SLIT("I8#") [] [] [intPrimTy] int8TyCon
304 int16TyCon = pcNonRecDataTyCon int16TyConKey iNT SLIT("Int16") [] [int16DataCon]
306 int16DataCon = pcDataCon int16DataConKey iNT SLIT("I16#") [] [] [intPrimTy] int16TyCon
308 int32TyCon = pcNonRecDataTyCon int32TyConKey iNT SLIT("Int32") [] [int32DataCon]
310 int32DataCon = pcDataCon int32DataConKey iNT SLIT("I32#") [] [] [intPrimTy] int32TyCon
312 int64TyCon = pcNonRecDataTyCon int64TyConKey pREL_ADDR SLIT("Int64") [] [int64DataCon]
314 int64DataCon = pcDataCon int64DataConKey pREL_ADDR SLIT("I64#") [] [] [int64PrimTy] int64TyCon
319 wordTy = mkTyConTy wordTyCon
321 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [wordDataCon]
322 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
324 word8TyCon = pcNonRecDataTyCon word8TyConKey wORD SLIT("Word8") [] [word8DataCon]
326 word8DataCon = pcDataCon word8DataConKey wORD SLIT("W8#") [] [] [wordPrimTy] word8TyCon
328 word16TyCon = pcNonRecDataTyCon word16TyConKey wORD SLIT("Word16") [] [word16DataCon]
330 word16DataCon = pcDataCon word16DataConKey wORD SLIT("W16#") [] [] [wordPrimTy] word16TyCon
332 word32TyCon = pcNonRecDataTyCon word32TyConKey wORD SLIT("Word32") [] [word32DataCon]
334 word32DataCon = pcDataCon word32DataConKey wORD SLIT("W32#") [] [] [wordPrimTy] word32TyCon
336 word64TyCon = pcNonRecDataTyCon word64TyConKey pREL_ADDR SLIT("Word64") [] [word64DataCon]
338 word64DataCon = pcDataCon word64DataConKey pREL_ADDR SLIT("W64#") [] [] [word64PrimTy] word64TyCon
342 addrTy = mkTyConTy addrTyCon
344 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [addrDataCon]
345 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
347 isAddrTy :: Type -> Bool
349 = case (splitAlgTyConApp_maybe ty) of
350 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
356 floatTy = mkTyConTy floatTyCon
358 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
359 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
361 isFloatTy :: Type -> Bool
363 = case (splitAlgTyConApp_maybe ty) of
364 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
370 doubleTy = mkTyConTy doubleTyCon
372 isDoubleTy :: Type -> Bool
374 = case (splitAlgTyConApp_maybe ty) of
375 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
378 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
379 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
384 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
385 alpha_tyvar [stablePtrDataCon]
388 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
389 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
394 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
395 [] [foreignObjDataCon]
398 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
399 [] [] [foreignObjPrimTy] foreignObjTyCon
402 %************************************************************************
404 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
406 %************************************************************************
408 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
411 integerTy = mkTyConTy integerTyCon
413 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [smallIntegerDataCon, largeIntegerDataCon]
415 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_BASE SLIT("S#")
416 [] [] [intPrimTy] integerTyCon
417 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_BASE SLIT("J#")
418 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
421 isIntegerTy :: Type -> Bool
423 = case (splitAlgTyConApp_maybe ty) of
424 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
429 %************************************************************************
431 \subsection[TysWiredIn-ext-type]{External types}
433 %************************************************************************
435 The compiler's foreign function interface supports the passing of a
436 restricted set of types as arguments and results (the restricting factor
440 isFFIArgumentTy :: Type -> Bool
442 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
443 case (splitAlgTyConApp_maybe ty) of
444 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
447 -- types that can be passed as arguments to "foreign" functions
449 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
450 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
451 , floatTyConKey, doubleTyConKey
452 , addrTyConKey, charTyConKey, foreignObjTyConKey
454 , byteArrayTyConKey, mutableByteArrayTyConKey
457 -- types that can be passed from the outside world into Haskell.
458 -- excludes (mutable) byteArrays.
459 isFFIExternalTy :: Type -> Bool
461 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
462 case (splitAlgTyConApp_maybe ty) of
463 Just (tycon, _, _) ->
465 u_tycon = getUnique tycon
467 (u_tycon `elem` primArgTyConKeys) &&
468 not (u_tycon `elem` notLegalExternalTyCons)
472 isFFIResultTy :: Type -> Bool
474 not (isUnLiftedType ty) &&
475 case (splitAlgTyConApp_maybe ty) of
476 Just (tycon, _, _) ->
478 u_tycon = getUnique tycon
480 (u_tycon == getUnique unitTyCon) ||
481 ((u_tycon `elem` primArgTyConKeys) &&
482 not (u_tycon `elem` notLegalExternalTyCons))
485 -- it's illegal to return foreign objects and (mutable)
486 -- bytearrays from a _ccall_ / foreign declaration
487 -- (or be passed them as arguments in foreign exported functions).
488 notLegalExternalTyCons =
489 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
493 %************************************************************************
495 \subsection[TysWiredIn-Bool]{The @Bool@ type}
497 %************************************************************************
499 An ordinary enumeration type, but deeply wired in. There are no
500 magical operations on @Bool@ (just the regular Prelude code).
502 {\em BEGIN IDLE SPECULATION BY SIMON}
504 This is not the only way to encode @Bool@. A more obvious coding makes
505 @Bool@ just a boxed up version of @Bool#@, like this:
508 data Bool = MkBool Bool#
511 Unfortunately, this doesn't correspond to what the Report says @Bool@
512 looks like! Furthermore, we get slightly less efficient code (I
513 think) with this coding. @gtInt@ would look like this:
516 gtInt :: Int -> Int -> Bool
517 gtInt x y = case x of I# x# ->
519 case (gtIntPrim x# y#) of
523 Notice that the result of the @gtIntPrim@ comparison has to be turned
524 into an integer (here called @b#@), and returned in a @MkBool@ box.
526 The @if@ expression would compile to this:
529 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
532 I think this code is a little less efficient than the previous code,
533 but I'm not certain. At all events, corresponding with the Report is
534 important. The interesting thing is that the language is expressive
535 enough to describe more than one alternative; and that a type doesn't
536 necessarily need to be a straightforwardly boxed version of its
537 primitive counterpart.
539 {\em END IDLE SPECULATION BY SIMON}
542 boolTy = mkTyConTy boolTyCon
544 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
545 pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
547 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
548 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
551 %************************************************************************
553 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
555 %************************************************************************
557 Special syntax, deeply wired in, but otherwise an ordinary algebraic
560 data [] a = [] | a : (List a)
562 data (,) a b = (,,) a b
567 mkListTy :: Type -> Type
568 mkListTy ty = mkTyConApp listTyCon [ty]
570 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
572 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
573 alpha_tyvar [nilDataCon, consDataCon]
575 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
576 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
577 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
578 -- Interesting: polymorphic recursion would help here.
579 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
580 -- gets the over-specific type (Type -> Type)
583 %************************************************************************
585 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
587 %************************************************************************
589 The tuple types are definitely magic, because they form an infinite
594 They have a special family of type constructors, of type @TyCon@
595 These contain the tycon arity, but don't require a Unique.
598 They have a special family of constructors, of type
599 @Id@. Again these contain their arity but don't need a Unique.
602 There should be a magic way of generating the info tables and
603 entry code for all tuples.
605 But at the moment we just compile a Haskell source
606 file\srcloc{lib/prelude/...} containing declarations like:
609 data Tuple2 a b = Tup2 a b
610 data Tuple3 a b c = Tup3 a b c
611 data Tuple4 a b c d = Tup4 a b c d
614 The print-names associated with the magic @Id@s for tuple constructors
615 ``just happen'' to be the same as those generated by these
619 The instance environment should have a magic way to know
620 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
621 so on. \ToDo{Not implemented yet.}
624 There should also be a way to generate the appropriate code for each
625 of these instances, but (like the info tables and entry code) it is
626 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
630 mkTupleTy :: Int -> [Type] -> Type
631 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
633 mkUnboxedTupleTy :: Int -> [Type] -> Type
634 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
636 unitTy = mkTupleTy 0 []