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.''
57 tupleTyCon, tupleCon, unitTyCon, unitDataCon, pairTyCon, pairDataCon,
61 unboxedTupleTyCon, unboxedTupleCon,
62 unboxedPairTyCon, unboxedPairDataCon,
82 isFFIArgumentTy, -- :: Type -> Bool
83 isFFIResultTy, -- :: Type -> Bool
84 isFFIExternalTy, -- :: Type -> Bool
85 isAddrTy, -- :: Type -> Bool
89 #include "HsVersions.h"
91 import {-# SOURCE #-} MkId( mkDataConId )
98 import Constants ( mAX_TUPLE_SIZE )
99 import Name ( Module, varOcc, mkWiredInTyConName, mkWiredInIdName )
100 import DataCon ( DataCon, mkDataCon )
101 import Var ( TyVar, tyVarKind )
102 import TyCon ( TyCon, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
103 import BasicTypes ( Arity, NewOrData(..),
104 RecFlag(..), StrictnessMark(..) )
105 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
106 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
107 mkFunTy, mkFunTys, isUnLiftedType,
108 splitTyConApp_maybe, splitAlgTyConApp_maybe,
110 import PrimRep ( PrimRep(..) )
112 import CmdLineOpts ( opt_GlasgowExts )
113 import Util ( assoc )
114 import Panic ( panic )
117 alpha_tyvar = [alphaTyVar]
119 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
121 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
122 :: Unique{-TyConKey-} -> Module -> FAST_STRING
123 -> [TyVar] -> [DataCon] -> TyCon
125 pcRecDataTyCon = pcTyCon DataType Recursive
126 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
127 pcNonRecNewTyCon = pcTyCon NewType NonRecursive
129 pcTyCon new_or_data is_rec key mod str tyvars cons
132 tycon = mkAlgTyCon name kind
137 Nothing -- Not a dictionary
141 name = mkWiredInTyConName key mod str tycon
142 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
144 pcSynTyCon key mod str kind arity tyvars expansion
147 tycon = mkSynTyCon name kind arity tyvars expansion
148 name = mkWiredInTyConName key mod str tycon
150 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
151 -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
152 pcDataCon key mod str tyvars context arg_tys tycon
155 data_con = mkDataCon name
156 [ NotMarkedStrict | a <- arg_tys ]
157 [ {- no labelled fields -} ]
158 tyvars context [] [] arg_tys tycon id
159 name = mkWiredInIdName key mod (varOcc str) id
160 id = mkDataConId data_con
163 %************************************************************************
165 \subsection[TysWiredIn-tuples]{The tuple types}
167 %************************************************************************
170 tupleTyCon :: Arity -> TyCon
171 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i) -- Build one specially
172 | otherwise = tupleTyConArr!i
174 tupleCon :: Arity -> DataCon
175 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i) -- Build one specially
176 | otherwise = tupleConArr!i
178 tupleTyCons :: [TyCon]
179 tupleTyCons = elems tupleTyConArr
181 tupleTyConArr :: Array Int TyCon
182 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
184 tupleConArr :: Array Int DataCon
185 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
187 tuples :: [(TyCon,DataCon)]
188 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
190 mk_tuple :: Int -> (TyCon,DataCon)
191 mk_tuple arity = (tycon, tuple_con)
193 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
194 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
195 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
197 tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
198 tyvars = take arity alphaTyVars
199 tyvar_tys = mkTyVarTys tyvars
200 (mod_name, name_str) = mkTupNameStr arity
201 tc_uniq = mkTupleTyConUnique arity
202 dc_uniq = mkTupleDataConUnique arity
204 unitTyCon = tupleTyCon 0
205 pairTyCon = tupleTyCon 2
207 unitDataCon = tupleCon 0
208 pairDataCon = tupleCon 2
211 %************************************************************************
213 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
215 %************************************************************************
218 unboxedTupleTyCon :: Arity -> TyCon
219 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
220 | otherwise = unboxedTupleTyConArr!i
222 unboxedTupleCon :: Arity -> DataCon
223 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
224 | otherwise = unboxedTupleConArr!i
226 unboxedTupleTyConArr :: Array Int TyCon
227 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
229 unboxedTupleConArr :: Array Int DataCon
230 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
232 ubx_tuples :: [(TyCon,DataCon)]
233 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
235 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
236 mk_unboxed_tuple arity = (tycon, tuple_con)
238 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
239 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
240 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
242 tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
243 tyvars = take arity openAlphaTyVars
244 tyvar_tys = mkTyVarTys tyvars
245 (mod_name, name_str) = mkUbxTupNameStr arity
246 tc_uniq = mkUbxTupleTyConUnique arity
247 dc_uniq = mkUbxTupleDataConUnique arity
249 unboxedPairTyCon = unboxedTupleTyCon 2
250 unboxedPairDataCon = unboxedTupleCon 2
253 %************************************************************************
255 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
257 %************************************************************************
260 -- The Void type is represented as a data type with no constructors
261 -- It's a built in type (i.e. there's no way to define it in Haskell;
262 -- the nearest would be
264 -- data Void = -- No constructors!
266 -- ) It's boxed; there is only one value of this
267 -- type, namely "void", whose semantics is just bottom.
269 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
276 charTy = mkTyConTy charTyCon
278 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [charDataCon]
279 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
281 stringTy = mkListTy charTy -- convenience only
285 intTy = mkTyConTy intTyCon
287 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
288 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
290 isIntTy :: Type -> Bool
292 = case (splitAlgTyConApp_maybe ty) of
293 Just (tycon, [], _) -> getUnique tycon == intTyConKey
296 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
297 inIntRange i = (min_int <= i) && (i <= max_int)
299 max_int, min_int :: Integer
300 max_int = toInteger maxInt
301 min_int = toInteger minInt
303 int8TyCon = pcNonRecDataTyCon int8TyConKey iNT SLIT("Int8") [] [int8DataCon]
305 int8DataCon = pcDataCon int8DataConKey iNT SLIT("I8#") [] [] [intPrimTy] int8TyCon
307 int16TyCon = pcNonRecDataTyCon int16TyConKey iNT SLIT("Int16") [] [int16DataCon]
309 int16DataCon = pcDataCon int16DataConKey iNT SLIT("I16#") [] [] [intPrimTy] int16TyCon
311 int32TyCon = pcNonRecDataTyCon int32TyConKey iNT SLIT("Int32") [] [int32DataCon]
313 int32DataCon = pcDataCon int32DataConKey iNT SLIT("I32#") [] [] [intPrimTy] int32TyCon
315 int64TyCon = pcNonRecDataTyCon int64TyConKey pREL_ADDR SLIT("Int64") [] [int64DataCon]
317 int64DataCon = pcDataCon int64DataConKey pREL_ADDR SLIT("I64#") [] [] [int64PrimTy] int64TyCon
322 wordTy = mkTyConTy wordTyCon
324 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [wordDataCon]
325 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
327 word8TyCon = pcNonRecDataTyCon word8TyConKey wORD SLIT("Word8") [] [word8DataCon]
329 word8DataCon = pcDataCon word8DataConKey wORD SLIT("W8#") [] [] [wordPrimTy] word8TyCon
331 word16TyCon = pcNonRecDataTyCon word16TyConKey wORD SLIT("Word16") [] [word16DataCon]
333 word16DataCon = pcDataCon word16DataConKey wORD SLIT("W16#") [] [] [wordPrimTy] word16TyCon
335 word32TyCon = pcNonRecDataTyCon word32TyConKey wORD SLIT("Word32") [] [word32DataCon]
337 word32DataCon = pcDataCon word32DataConKey wORD SLIT("W32#") [] [] [wordPrimTy] word32TyCon
339 word64TyCon = pcNonRecDataTyCon word64TyConKey pREL_ADDR SLIT("Word64") [] [word64DataCon]
341 word64DataCon = pcDataCon word64DataConKey pREL_ADDR SLIT("W64#") [] [] [word64PrimTy] word64TyCon
345 addrTy = mkTyConTy addrTyCon
347 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [addrDataCon]
348 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
350 isAddrTy :: Type -> Bool
352 = case (splitAlgTyConApp_maybe ty) of
353 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
359 floatTy = mkTyConTy floatTyCon
361 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
362 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
364 isFloatTy :: Type -> Bool
366 = case (splitAlgTyConApp_maybe ty) of
367 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
373 doubleTy = mkTyConTy doubleTyCon
375 isDoubleTy :: Type -> Bool
377 = case (splitAlgTyConApp_maybe ty) of
378 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
381 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
382 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
386 mkStateTy ty = mkTyConApp stateTyCon [ty]
387 realWorldStateTy = mkStateTy realWorldTy -- a common use
389 stateTyCon = pcNonRecDataTyCon stateTyConKey pREL_ST SLIT("State") alpha_tyvar [stateDataCon]
391 = pcDataCon stateDataConKey pREL_ST SLIT("S#")
392 alpha_tyvar [] [mkStatePrimTy alphaTy] stateTyCon
397 = pcNonRecDataTyCon stablePtrTyConKey pREL_FOREIGN SLIT("StablePtr")
398 alpha_tyvar [stablePtrDataCon]
401 = pcDataCon stablePtrDataConKey pREL_FOREIGN SLIT("StablePtr")
402 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
407 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
408 [] [foreignObjDataCon]
411 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
412 [] [] [foreignObjPrimTy] foreignObjTyCon
415 %************************************************************************
417 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
419 %************************************************************************
421 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
424 integerTy = mkTyConTy integerTyCon
426 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [integerDataCon]
428 integerDataCon = pcDataCon integerDataConKey pREL_BASE SLIT("J#")
429 [] [] [intPrimTy, intPrimTy, byteArrayPrimTy] integerTyCon
431 isIntegerTy :: Type -> Bool
433 = case (splitAlgTyConApp_maybe ty) of
434 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
439 %************************************************************************
441 \subsection[TysWiredIn-ext-type]{External types}
443 %************************************************************************
445 The compiler's foreign function interface supports the passing of a
446 restricted set of types as arguments and results (the restricting factor
450 isFFIArgumentTy :: Type -> Bool
452 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
453 case (splitAlgTyConApp_maybe ty) of
454 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
457 -- types that can be passed as arguments to "foreign" functions
459 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
460 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
461 , floatTyConKey, doubleTyConKey
462 , addrTyConKey, charTyConKey, foreignObjTyConKey
463 , stablePtrTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey
466 -- types that can be passed from the outside world into Haskell.
467 -- excludes (mutable) byteArrays.
468 isFFIExternalTy :: Type -> Bool
470 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
471 case (splitAlgTyConApp_maybe ty) of
472 Just (tycon, _, _) ->
474 u_tycon = getUnique tycon
476 (u_tycon `elem` primArgTyConKeys) &&
477 not (u_tycon `elem` notLegalExternalTyCons)
481 isFFIResultTy :: Type -> Bool
483 not (isUnLiftedType ty) &&
484 case (splitAlgTyConApp_maybe ty) of
485 Just (tycon, _, _) ->
487 u_tycon = getUnique tycon
489 (u_tycon == getUnique unitTyCon) ||
490 ((u_tycon `elem` primArgTyConKeys) &&
491 not (u_tycon `elem` notLegalExternalTyCons))
494 -- it's illegal to return foreign objects and (mutable)
495 -- bytearrays from a _ccall_ / foreign declaration
496 -- (or be passed them as arguments in foreign exported functions).
497 notLegalExternalTyCons =
498 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
502 %************************************************************************
504 \subsection[TysWiredIn-Bool]{The @Bool@ type}
506 %************************************************************************
508 An ordinary enumeration type, but deeply wired in. There are no
509 magical operations on @Bool@ (just the regular Prelude code).
511 {\em BEGIN IDLE SPECULATION BY SIMON}
513 This is not the only way to encode @Bool@. A more obvious coding makes
514 @Bool@ just a boxed up version of @Bool#@, like this:
517 data Bool = MkBool Bool#
520 Unfortunately, this doesn't correspond to what the Report says @Bool@
521 looks like! Furthermore, we get slightly less efficient code (I
522 think) with this coding. @gtInt@ would look like this:
525 gtInt :: Int -> Int -> Bool
526 gtInt x y = case x of I# x# ->
528 case (gtIntPrim x# y#) of
532 Notice that the result of the @gtIntPrim@ comparison has to be turned
533 into an integer (here called @b#@), and returned in a @MkBool@ box.
535 The @if@ expression would compile to this:
538 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
541 I think this code is a little less efficient than the previous code,
542 but I'm not certain. At all events, corresponding with the Report is
543 important. The interesting thing is that the language is expressive
544 enough to describe more than one alternative; and that a type doesn't
545 necessarily need to be a straightforwardly boxed version of its
546 primitive counterpart.
548 {\em END IDLE SPECULATION BY SIMON}
551 boolTy = mkTyConTy boolTyCon
553 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
554 pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
556 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
557 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
560 %************************************************************************
562 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
564 %************************************************************************
566 Special syntax, deeply wired in, but otherwise an ordinary algebraic
569 data [] a = [] | a : (List a)
571 data (,) a b = (,,) a b
576 mkListTy :: Type -> Type
577 mkListTy ty = mkTyConApp listTyCon [ty]
579 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
581 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
582 alpha_tyvar [nilDataCon, consDataCon]
584 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
585 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
586 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
587 -- Interesting: polymorphic recursion would help here.
588 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
589 -- gets the over-specific type (Type -> Type)
592 %************************************************************************
594 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
596 %************************************************************************
598 The tuple types are definitely magic, because they form an infinite
603 They have a special family of type constructors, of type @TyCon@
604 These contain the tycon arity, but don't require a Unique.
607 They have a special family of constructors, of type
608 @Id@. Again these contain their arity but don't need a Unique.
611 There should be a magic way of generating the info tables and
612 entry code for all tuples.
614 But at the moment we just compile a Haskell source
615 file\srcloc{lib/prelude/...} containing declarations like:
618 data Tuple2 a b = Tup2 a b
619 data Tuple3 a b c = Tup3 a b c
620 data Tuple4 a b c d = Tup4 a b c d
623 The print-names associated with the magic @Id@s for tuple constructors
624 ``just happen'' to be the same as those generated by these
628 The instance environment should have a magic way to know
629 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
630 so on. \ToDo{Not implemented yet.}
633 There should also be a way to generate the appropriate code for each
634 of these instances, but (like the info tables and entry code) it is
635 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
639 mkTupleTy :: Int -> [Type] -> Type
640 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
642 mkUnboxedTupleTy :: Int -> [Type] -> Type
643 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
645 unitTy = mkTupleTy 0 []