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.''
52 tupleTyCon, tupleCon, unitTyCon, unitDataCon, pairTyCon, pairDataCon,
56 unboxedTupleTyCon, unboxedTupleCon,
57 unboxedPairTyCon, unboxedPairDataCon,
68 isFFIArgumentTy, -- :: Type -> Bool
69 isFFIResultTy, -- :: Type -> Bool
70 isFFIExternalTy, -- :: Type -> Bool
71 isAddrTy, -- :: Type -> Bool
75 #include "HsVersions.h"
77 import {-# SOURCE #-} MkId( mkDataConId )
84 import Constants ( mAX_TUPLE_SIZE )
85 import Module ( Module, mkPrelModule )
86 import Name ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, dataName )
87 import DataCon ( DataCon, StrictnessMark(..), mkDataCon )
88 import Var ( TyVar, tyVarKind )
89 import TyCon ( TyCon, ArgVrcs, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
90 import BasicTypes ( Arity, NewOrData(..), RecFlag(..) )
91 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
92 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
93 mkFunTy, mkFunTys, isUnLiftedType,
94 splitTyConApp_maybe, splitAlgTyConApp_maybe,
96 import PrimRep ( PrimRep(..) )
98 import CmdLineOpts ( opt_GlasgowExts )
100 import Panic ( panic )
103 alpha_tyvar = [alphaTyVar]
105 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
107 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
108 :: Unique{-TyConKey-} -> Module -> FAST_STRING
109 -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
111 pcRecDataTyCon = pcTyCon DataType Recursive
112 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
113 pcNonRecNewTyCon = pcTyCon NewType NonRecursive
115 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
118 tycon = mkAlgTyCon name kind
124 Nothing -- Not a dictionary
128 name = mkWiredInTyConName key mod str tycon
129 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
131 pcSynTyCon key mod str kind arity tyvars expansion argvrcs -- this fun never used!
134 tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
135 name = mkWiredInTyConName key mod str tycon
137 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
138 -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
139 pcDataCon key mod str tyvars context arg_tys tycon
142 data_con = mkDataCon name
143 [ NotMarkedStrict | a <- arg_tys ]
144 [ {- no labelled fields -} ]
145 tyvars context [] [] arg_tys tycon id
146 name = mkWiredInIdName key mod (mkSrcOccFS dataName str) id
147 id = mkDataConId data_con
150 %************************************************************************
152 \subsection[TysWiredIn-tuples]{The tuple types}
154 %************************************************************************
157 tupleTyCon :: Arity -> TyCon
158 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i) -- Build one specially
159 | otherwise = tupleTyConArr!i
161 tupleCon :: Arity -> DataCon
162 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i) -- Build one specially
163 | otherwise = tupleConArr!i
165 tupleTyCons :: [TyCon]
166 tupleTyCons = elems tupleTyConArr
168 tupleTyConArr :: Array Int TyCon
169 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
171 tupleConArr :: Array Int DataCon
172 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
174 tuples :: [(TyCon,DataCon)]
175 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
177 mk_tuple :: Int -> (TyCon,DataCon)
178 mk_tuple arity = (tycon, tuple_con)
180 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
181 tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
182 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
184 tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
185 tyvars = take arity alphaTyVars
186 tyvar_tys = mkTyVarTys tyvars
187 (mod_name, name_str) = mkTupNameStr arity
188 tc_uniq = mkTupleTyConUnique arity
189 dc_uniq = mkTupleDataConUnique arity
190 mod = mkPrelModule mod_name
192 unitTyCon = tupleTyCon 0
193 pairTyCon = tupleTyCon 2
195 unitDataCon = tupleCon 0
196 pairDataCon = tupleCon 2
199 %************************************************************************
201 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
203 %************************************************************************
206 unboxedTupleTyCon :: Arity -> TyCon
207 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
208 | otherwise = unboxedTupleTyConArr!i
210 unboxedTupleCon :: Arity -> DataCon
211 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
212 | otherwise = unboxedTupleConArr!i
214 unboxedTupleTyConArr :: Array Int TyCon
215 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
217 unboxedTupleConArr :: Array Int DataCon
218 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
220 ubx_tuples :: [(TyCon,DataCon)]
221 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
223 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
224 mk_unboxed_tuple arity = (tycon, tuple_con)
226 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
227 tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
228 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
230 tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
231 tyvars = take arity openAlphaTyVars
232 tyvar_tys = mkTyVarTys tyvars
233 (mod_name, name_str) = mkUbxTupNameStr arity
234 tc_uniq = mkUbxTupleTyConUnique arity
235 dc_uniq = mkUbxTupleDataConUnique arity
236 mod = mkPrelModule mod_name
238 unboxedPairTyCon = unboxedTupleTyCon 2
239 unboxedPairDataCon = unboxedTupleCon 2
242 %************************************************************************
244 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
246 %************************************************************************
249 -- The Void type is represented as a data type with no constructors
250 -- It's a built in type (i.e. there's no way to define it in Haskell;
251 -- the nearest would be
253 -- data Void = -- No constructors!
255 -- ) It's boxed; there is only one value of this
256 -- type, namely "void", whose semantics is just bottom.
258 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
265 charTy = mkTyConTy charTyCon
267 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [] [charDataCon]
268 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
270 stringTy = mkListTy charTy -- convenience only
274 intTy = mkTyConTy intTyCon
276 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
277 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
279 isIntTy :: Type -> Bool
281 = case (splitAlgTyConApp_maybe ty) of
282 Just (tycon, [], _) -> getUnique tycon == intTyConKey
285 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
286 inIntRange i = (min_int <= i) && (i <= max_int)
288 max_int, min_int :: Integer
289 max_int = toInteger maxInt
290 min_int = toInteger minInt
296 wordTy = mkTyConTy wordTyCon
298 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [] [wordDataCon]
299 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
303 addrTy = mkTyConTy addrTyCon
305 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
306 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
308 isAddrTy :: Type -> Bool
310 = case (splitAlgTyConApp_maybe ty) of
311 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
317 floatTy = mkTyConTy floatTyCon
319 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [] [floatDataCon]
320 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
322 isFloatTy :: Type -> Bool
324 = case (splitAlgTyConApp_maybe ty) of
325 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
331 doubleTy = mkTyConTy doubleTyCon
333 isDoubleTy :: Type -> Bool
335 = case (splitAlgTyConApp_maybe ty) of
336 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
339 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [] [doubleDataCon]
340 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
345 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
346 alpha_tyvar [(True,False)] [stablePtrDataCon]
349 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
350 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
355 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
356 [] [] [foreignObjDataCon]
359 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
360 [] [] [foreignObjPrimTy] foreignObjTyCon
363 %************************************************************************
365 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
367 %************************************************************************
369 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
372 integerTy = mkTyConTy integerTyCon
374 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer")
375 [] [] [smallIntegerDataCon, largeIntegerDataCon]
377 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_BASE SLIT("S#")
378 [] [] [intPrimTy] integerTyCon
379 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_BASE SLIT("J#")
380 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
383 isIntegerTy :: Type -> Bool
385 = case (splitAlgTyConApp_maybe ty) of
386 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
391 %************************************************************************
393 \subsection[TysWiredIn-ext-type]{External types}
395 %************************************************************************
397 The compiler's foreign function interface supports the passing of a
398 restricted set of types as arguments and results (the restricting factor
402 isFFIArgumentTy :: Type -> Bool
404 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
405 case (splitAlgTyConApp_maybe ty) of
406 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
409 -- types that can be passed as arguments to "foreign" functions
411 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
412 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
413 , floatTyConKey, doubleTyConKey
414 , addrTyConKey, charTyConKey, foreignObjTyConKey
416 , byteArrayTyConKey, mutableByteArrayTyConKey
419 -- types that can be passed from the outside world into Haskell.
420 -- excludes (mutable) byteArrays.
421 isFFIExternalTy :: Type -> Bool
423 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
424 case (splitAlgTyConApp_maybe ty) of
425 Just (tycon, _, _) ->
427 u_tycon = getUnique tycon
429 (u_tycon `elem` primArgTyConKeys) &&
430 not (u_tycon `elem` notLegalExternalTyCons)
434 isFFIResultTy :: Type -> Bool
436 not (isUnLiftedType ty) &&
437 case (splitAlgTyConApp_maybe ty) of
438 Just (tycon, _, _) ->
440 u_tycon = getUnique tycon
442 (u_tycon == getUnique unitTyCon) ||
443 ((u_tycon `elem` primArgTyConKeys) &&
444 not (u_tycon `elem` notLegalExternalTyCons))
447 -- it's illegal to return foreign objects and (mutable)
448 -- bytearrays from a _ccall_ / foreign declaration
449 -- (or be passed them as arguments in foreign exported functions).
450 notLegalExternalTyCons =
451 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
455 %************************************************************************
457 \subsection[TysWiredIn-Bool]{The @Bool@ type}
459 %************************************************************************
461 An ordinary enumeration type, but deeply wired in. There are no
462 magical operations on @Bool@ (just the regular Prelude code).
464 {\em BEGIN IDLE SPECULATION BY SIMON}
466 This is not the only way to encode @Bool@. A more obvious coding makes
467 @Bool@ just a boxed up version of @Bool#@, like this:
470 data Bool = MkBool Bool#
473 Unfortunately, this doesn't correspond to what the Report says @Bool@
474 looks like! Furthermore, we get slightly less efficient code (I
475 think) with this coding. @gtInt@ would look like this:
478 gtInt :: Int -> Int -> Bool
479 gtInt x y = case x of I# x# ->
481 case (gtIntPrim x# y#) of
485 Notice that the result of the @gtIntPrim@ comparison has to be turned
486 into an integer (here called @b#@), and returned in a @MkBool@ box.
488 The @if@ expression would compile to this:
491 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
494 I think this code is a little less efficient than the previous code,
495 but I'm not certain. At all events, corresponding with the Report is
496 important. The interesting thing is that the language is expressive
497 enough to describe more than one alternative; and that a type doesn't
498 necessarily need to be a straightforwardly boxed version of its
499 primitive counterpart.
501 {\em END IDLE SPECULATION BY SIMON}
504 boolTy = mkTyConTy boolTyCon
506 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
507 pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
509 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
510 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
513 %************************************************************************
515 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
517 %************************************************************************
519 Special syntax, deeply wired in, but otherwise an ordinary algebraic
522 data [] a = [] | a : (List a)
524 data (,) a b = (,,) a b
529 mkListTy :: Type -> Type
530 mkListTy ty = mkTyConApp listTyCon [ty]
532 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
534 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
535 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
537 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
538 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
539 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
540 -- Interesting: polymorphic recursion would help here.
541 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
542 -- gets the over-specific type (Type -> Type)
545 %************************************************************************
547 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
549 %************************************************************************
551 The tuple types are definitely magic, because they form an infinite
556 They have a special family of type constructors, of type @TyCon@
557 These contain the tycon arity, but don't require a Unique.
560 They have a special family of constructors, of type
561 @Id@. Again these contain their arity but don't need a Unique.
564 There should be a magic way of generating the info tables and
565 entry code for all tuples.
567 But at the moment we just compile a Haskell source
568 file\srcloc{lib/prelude/...} containing declarations like:
571 data Tuple2 a b = Tup2 a b
572 data Tuple3 a b c = Tup3 a b c
573 data Tuple4 a b c d = Tup4 a b c d
576 The print-names associated with the magic @Id@s for tuple constructors
577 ``just happen'' to be the same as those generated by these
581 The instance environment should have a magic way to know
582 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
583 so on. \ToDo{Not implemented yet.}
586 There should also be a way to generate the appropriate code for each
587 of these instances, but (like the info tables and entry code) it is
588 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
592 mkTupleTy :: Int -> [Type] -> Type
593 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
595 mkUnboxedTupleTy :: Int -> [Type] -> Type
596 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
598 unitTy = mkTupleTy 0 []