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 Module ( Module )
97 import Name ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, dataName )
98 import DataCon ( DataCon, mkDataCon )
99 import Var ( TyVar, tyVarKind )
100 import TyCon ( TyCon, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
101 import BasicTypes ( Arity, NewOrData(..),
102 RecFlag(..), StrictnessMark(..) )
103 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
104 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
105 mkFunTy, mkFunTys, isUnLiftedType,
106 splitTyConApp_maybe, splitAlgTyConApp_maybe,
108 import PrimRep ( PrimRep(..) )
110 import CmdLineOpts ( opt_GlasgowExts )
111 import Util ( assoc )
112 import Panic ( panic )
115 alpha_tyvar = [alphaTyVar]
117 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
119 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
120 :: Unique{-TyConKey-} -> Module -> FAST_STRING
121 -> [TyVar] -> [DataCon] -> TyCon
123 pcRecDataTyCon = pcTyCon DataType Recursive
124 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
125 pcNonRecNewTyCon = pcTyCon NewType NonRecursive
127 pcTyCon new_or_data is_rec key mod str tyvars cons
130 tycon = mkAlgTyCon name kind
135 Nothing -- Not a dictionary
139 name = mkWiredInTyConName key mod str tycon
140 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
142 pcSynTyCon key mod str kind arity tyvars expansion
145 tycon = mkSynTyCon name kind arity tyvars expansion
146 name = mkWiredInTyConName key mod str tycon
148 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
149 -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
150 pcDataCon key mod str tyvars context arg_tys tycon
153 data_con = mkDataCon name
154 [ NotMarkedStrict | a <- arg_tys ]
155 [ {- no labelled fields -} ]
156 tyvars context [] [] arg_tys tycon id
157 name = mkWiredInIdName key mod (mkSrcOccFS dataName str) id
158 id = mkDataConId data_con
161 %************************************************************************
163 \subsection[TysWiredIn-tuples]{The tuple types}
165 %************************************************************************
168 tupleTyCon :: Arity -> TyCon
169 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i) -- Build one specially
170 | otherwise = tupleTyConArr!i
172 tupleCon :: Arity -> DataCon
173 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i) -- Build one specially
174 | otherwise = tupleConArr!i
176 tupleTyCons :: [TyCon]
177 tupleTyCons = elems tupleTyConArr
179 tupleTyConArr :: Array Int TyCon
180 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
182 tupleConArr :: Array Int DataCon
183 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
185 tuples :: [(TyCon,DataCon)]
186 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
188 mk_tuple :: Int -> (TyCon,DataCon)
189 mk_tuple arity = (tycon, tuple_con)
191 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
192 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
193 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
195 tuple_con = pcDataCon dc_uniq mod_name 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
202 unitTyCon = tupleTyCon 0
203 pairTyCon = tupleTyCon 2
205 unitDataCon = tupleCon 0
206 pairDataCon = tupleCon 2
209 %************************************************************************
211 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
213 %************************************************************************
216 unboxedTupleTyCon :: Arity -> TyCon
217 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
218 | otherwise = unboxedTupleTyConArr!i
220 unboxedTupleCon :: Arity -> DataCon
221 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
222 | otherwise = unboxedTupleConArr!i
224 unboxedTupleTyConArr :: Array Int TyCon
225 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
227 unboxedTupleConArr :: Array Int DataCon
228 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
230 ubx_tuples :: [(TyCon,DataCon)]
231 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
233 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
234 mk_unboxed_tuple arity = (tycon, tuple_con)
236 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
237 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
238 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
240 tuple_con = pcDataCon dc_uniq mod_name 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
247 unboxedPairTyCon = unboxedTupleTyCon 2
248 unboxedPairDataCon = unboxedTupleCon 2
251 %************************************************************************
253 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
255 %************************************************************************
258 -- The Void type is represented as a data type with no constructors
259 -- It's a built in type (i.e. there's no way to define it in Haskell;
260 -- the nearest would be
262 -- data Void = -- No constructors!
264 -- ) It's boxed; there is only one value of this
265 -- type, namely "void", whose semantics is just bottom.
267 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
274 charTy = mkTyConTy charTyCon
276 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [charDataCon]
277 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
279 stringTy = mkListTy charTy -- convenience only
283 intTy = mkTyConTy intTyCon
285 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
286 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
288 isIntTy :: Type -> Bool
290 = case (splitAlgTyConApp_maybe ty) of
291 Just (tycon, [], _) -> getUnique tycon == intTyConKey
294 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
295 inIntRange i = (min_int <= i) && (i <= max_int)
297 max_int, min_int :: Integer
298 max_int = toInteger maxInt
299 min_int = toInteger minInt
301 int8TyCon = pcNonRecDataTyCon int8TyConKey iNT SLIT("Int8") [] [int8DataCon]
303 int8DataCon = pcDataCon int8DataConKey iNT SLIT("I8#") [] [] [intPrimTy] int8TyCon
305 int16TyCon = pcNonRecDataTyCon int16TyConKey iNT SLIT("Int16") [] [int16DataCon]
307 int16DataCon = pcDataCon int16DataConKey iNT SLIT("I16#") [] [] [intPrimTy] int16TyCon
309 int32TyCon = pcNonRecDataTyCon int32TyConKey iNT SLIT("Int32") [] [int32DataCon]
311 int32DataCon = pcDataCon int32DataConKey iNT SLIT("I32#") [] [] [intPrimTy] int32TyCon
313 int64TyCon = pcNonRecDataTyCon int64TyConKey pREL_ADDR SLIT("Int64") [] [int64DataCon]
315 int64DataCon = pcDataCon int64DataConKey pREL_ADDR SLIT("I64#") [] [] [int64PrimTy] int64TyCon
320 wordTy = mkTyConTy wordTyCon
322 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [wordDataCon]
323 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
325 word8TyCon = pcNonRecDataTyCon word8TyConKey wORD SLIT("Word8") [] [word8DataCon]
327 word8DataCon = pcDataCon word8DataConKey wORD SLIT("W8#") [] [] [wordPrimTy] word8TyCon
329 word16TyCon = pcNonRecDataTyCon word16TyConKey wORD SLIT("Word16") [] [word16DataCon]
331 word16DataCon = pcDataCon word16DataConKey wORD SLIT("W16#") [] [] [wordPrimTy] word16TyCon
333 word32TyCon = pcNonRecDataTyCon word32TyConKey wORD SLIT("Word32") [] [word32DataCon]
335 word32DataCon = pcDataCon word32DataConKey wORD SLIT("W32#") [] [] [wordPrimTy] word32TyCon
337 word64TyCon = pcNonRecDataTyCon word64TyConKey pREL_ADDR SLIT("Word64") [] [word64DataCon]
339 word64DataCon = pcDataCon word64DataConKey pREL_ADDR SLIT("W64#") [] [] [word64PrimTy] word64TyCon
343 addrTy = mkTyConTy addrTyCon
345 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [addrDataCon]
346 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
348 isAddrTy :: Type -> Bool
350 = case (splitAlgTyConApp_maybe ty) of
351 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
357 floatTy = mkTyConTy floatTyCon
359 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
360 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
362 isFloatTy :: Type -> Bool
364 = case (splitAlgTyConApp_maybe ty) of
365 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
371 doubleTy = mkTyConTy doubleTyCon
373 isDoubleTy :: Type -> Bool
375 = case (splitAlgTyConApp_maybe ty) of
376 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
379 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
380 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
385 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
386 alpha_tyvar [stablePtrDataCon]
389 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
390 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
395 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
396 [] [foreignObjDataCon]
399 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
400 [] [] [foreignObjPrimTy] foreignObjTyCon
403 %************************************************************************
405 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
407 %************************************************************************
409 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
412 integerTy = mkTyConTy integerTyCon
414 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [smallIntegerDataCon, largeIntegerDataCon]
416 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_BASE SLIT("S#")
417 [] [] [intPrimTy] integerTyCon
418 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_BASE SLIT("J#")
419 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
422 isIntegerTy :: Type -> Bool
424 = case (splitAlgTyConApp_maybe ty) of
425 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
430 %************************************************************************
432 \subsection[TysWiredIn-ext-type]{External types}
434 %************************************************************************
436 The compiler's foreign function interface supports the passing of a
437 restricted set of types as arguments and results (the restricting factor
441 isFFIArgumentTy :: Type -> Bool
443 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
444 case (splitAlgTyConApp_maybe ty) of
445 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
448 -- types that can be passed as arguments to "foreign" functions
450 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
451 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
452 , floatTyConKey, doubleTyConKey
453 , addrTyConKey, charTyConKey, foreignObjTyConKey
455 , byteArrayTyConKey, mutableByteArrayTyConKey
458 -- types that can be passed from the outside world into Haskell.
459 -- excludes (mutable) byteArrays.
460 isFFIExternalTy :: Type -> Bool
462 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
463 case (splitAlgTyConApp_maybe ty) of
464 Just (tycon, _, _) ->
466 u_tycon = getUnique tycon
468 (u_tycon `elem` primArgTyConKeys) &&
469 not (u_tycon `elem` notLegalExternalTyCons)
473 isFFIResultTy :: Type -> Bool
475 not (isUnLiftedType ty) &&
476 case (splitAlgTyConApp_maybe ty) of
477 Just (tycon, _, _) ->
479 u_tycon = getUnique tycon
481 (u_tycon == getUnique unitTyCon) ||
482 ((u_tycon `elem` primArgTyConKeys) &&
483 not (u_tycon `elem` notLegalExternalTyCons))
486 -- it's illegal to return foreign objects and (mutable)
487 -- bytearrays from a _ccall_ / foreign declaration
488 -- (or be passed them as arguments in foreign exported functions).
489 notLegalExternalTyCons =
490 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
494 %************************************************************************
496 \subsection[TysWiredIn-Bool]{The @Bool@ type}
498 %************************************************************************
500 An ordinary enumeration type, but deeply wired in. There are no
501 magical operations on @Bool@ (just the regular Prelude code).
503 {\em BEGIN IDLE SPECULATION BY SIMON}
505 This is not the only way to encode @Bool@. A more obvious coding makes
506 @Bool@ just a boxed up version of @Bool#@, like this:
509 data Bool = MkBool Bool#
512 Unfortunately, this doesn't correspond to what the Report says @Bool@
513 looks like! Furthermore, we get slightly less efficient code (I
514 think) with this coding. @gtInt@ would look like this:
517 gtInt :: Int -> Int -> Bool
518 gtInt x y = case x of I# x# ->
520 case (gtIntPrim x# y#) of
524 Notice that the result of the @gtIntPrim@ comparison has to be turned
525 into an integer (here called @b#@), and returned in a @MkBool@ box.
527 The @if@ expression would compile to this:
530 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
533 I think this code is a little less efficient than the previous code,
534 but I'm not certain. At all events, corresponding with the Report is
535 important. The interesting thing is that the language is expressive
536 enough to describe more than one alternative; and that a type doesn't
537 necessarily need to be a straightforwardly boxed version of its
538 primitive counterpart.
540 {\em END IDLE SPECULATION BY SIMON}
543 boolTy = mkTyConTy boolTyCon
545 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
546 pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
548 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
549 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
552 %************************************************************************
554 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
556 %************************************************************************
558 Special syntax, deeply wired in, but otherwise an ordinary algebraic
561 data [] a = [] | a : (List a)
563 data (,) a b = (,,) a b
568 mkListTy :: Type -> Type
569 mkListTy ty = mkTyConApp listTyCon [ty]
571 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
573 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
574 alpha_tyvar [nilDataCon, consDataCon]
576 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
577 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
578 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
579 -- Interesting: polymorphic recursion would help here.
580 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
581 -- gets the over-specific type (Type -> Type)
584 %************************************************************************
586 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
588 %************************************************************************
590 The tuple types are definitely magic, because they form an infinite
595 They have a special family of type constructors, of type @TyCon@
596 These contain the tycon arity, but don't require a Unique.
599 They have a special family of constructors, of type
600 @Id@. Again these contain their arity but don't need a Unique.
603 There should be a magic way of generating the info tables and
604 entry code for all tuples.
606 But at the moment we just compile a Haskell source
607 file\srcloc{lib/prelude/...} containing declarations like:
610 data Tuple2 a b = Tup2 a b
611 data Tuple3 a b c = Tup3 a b c
612 data Tuple4 a b c d = Tup4 a b c d
615 The print-names associated with the magic @Id@s for tuple constructors
616 ``just happen'' to be the same as those generated by these
620 The instance environment should have a magic way to know
621 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
622 so on. \ToDo{Not implemented yet.}
625 There should also be a way to generate the appropriate code for each
626 of these instances, but (like the info tables and entry code) it is
627 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
631 mkTupleTy :: Int -> [Type] -> Type
632 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
634 mkUnboxedTupleTy :: Int -> [Type] -> Type
635 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
637 unitTy = mkTupleTy 0 []