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 )
86 import Name ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, dataName )
87 import DataCon ( DataCon, mkDataCon )
88 import Var ( TyVar, tyVarKind )
89 import TyCon ( TyCon, ArgVrcs, mkAlgTyCon, mkSynTyCon, mkTupleTyCon )
90 import BasicTypes ( Arity, NewOrData(..),
91 RecFlag(..), StrictnessMark(..) )
92 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
93 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
94 mkFunTy, mkFunTys, isUnLiftedType,
95 splitTyConApp_maybe, splitAlgTyConApp_maybe,
97 import PrimRep ( PrimRep(..) )
99 import CmdLineOpts ( opt_GlasgowExts )
100 import Util ( assoc )
101 import Panic ( panic )
104 alpha_tyvar = [alphaTyVar]
106 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
108 pcRecDataTyCon, pcNonRecDataTyCon, pcNonRecNewTyCon
109 :: Unique{-TyConKey-} -> Module -> FAST_STRING
110 -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
112 pcRecDataTyCon = pcTyCon DataType Recursive
113 pcNonRecDataTyCon = pcTyCon DataType NonRecursive
114 pcNonRecNewTyCon = pcTyCon NewType NonRecursive
116 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
119 tycon = mkAlgTyCon name kind
125 Nothing -- Not a dictionary
129 name = mkWiredInTyConName key mod str tycon
130 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
132 pcSynTyCon key mod str kind arity tyvars expansion argvrcs -- this fun never used!
135 tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
136 name = mkWiredInTyConName key mod str tycon
138 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
139 -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
140 pcDataCon key mod str tyvars context arg_tys tycon
143 data_con = mkDataCon name
144 [ NotMarkedStrict | a <- arg_tys ]
145 [ {- no labelled fields -} ]
146 tyvars context [] [] arg_tys tycon id
147 name = mkWiredInIdName key mod (mkSrcOccFS dataName str) id
148 id = mkDataConId data_con
151 %************************************************************************
153 \subsection[TysWiredIn-tuples]{The tuple types}
155 %************************************************************************
158 tupleTyCon :: Arity -> TyCon
159 tupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_tuple i) -- Build one specially
160 | otherwise = tupleTyConArr!i
162 tupleCon :: Arity -> DataCon
163 tupleCon i | i > mAX_TUPLE_SIZE = snd (mk_tuple i) -- Build one specially
164 | otherwise = tupleConArr!i
166 tupleTyCons :: [TyCon]
167 tupleTyCons = elems tupleTyConArr
169 tupleTyConArr :: Array Int TyCon
170 tupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst tuples)
172 tupleConArr :: Array Int DataCon
173 tupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd tuples)
175 tuples :: [(TyCon,DataCon)]
176 tuples = [mk_tuple i | i <- [0..mAX_TUPLE_SIZE]]
178 mk_tuple :: Int -> (TyCon,DataCon)
179 mk_tuple arity = (tycon, tuple_con)
181 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con True
182 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
183 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
185 tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
186 tyvars = take arity alphaTyVars
187 tyvar_tys = mkTyVarTys tyvars
188 (mod_name, name_str) = mkTupNameStr arity
189 tc_uniq = mkTupleTyConUnique arity
190 dc_uniq = mkTupleDataConUnique arity
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 name_str tycon
228 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
230 tuple_con = pcDataCon dc_uniq mod_name 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
237 unboxedPairTyCon = unboxedTupleTyCon 2
238 unboxedPairDataCon = unboxedTupleCon 2
241 %************************************************************************
243 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
245 %************************************************************************
248 -- The Void type is represented as a data type with no constructors
249 -- It's a built in type (i.e. there's no way to define it in Haskell;
250 -- the nearest would be
252 -- data Void = -- No constructors!
254 -- ) It's boxed; there is only one value of this
255 -- type, namely "void", whose semantics is just bottom.
257 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
264 charTy = mkTyConTy charTyCon
266 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [] [charDataCon]
267 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
269 stringTy = mkListTy charTy -- convenience only
273 intTy = mkTyConTy intTyCon
275 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
276 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
278 isIntTy :: Type -> Bool
280 = case (splitAlgTyConApp_maybe ty) of
281 Just (tycon, [], _) -> getUnique tycon == intTyConKey
284 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
285 inIntRange i = (min_int <= i) && (i <= max_int)
287 max_int, min_int :: Integer
288 max_int = toInteger maxInt
289 min_int = toInteger minInt
295 wordTy = mkTyConTy wordTyCon
297 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [] [wordDataCon]
298 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
302 addrTy = mkTyConTy addrTyCon
304 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
305 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
307 isAddrTy :: Type -> Bool
309 = case (splitAlgTyConApp_maybe ty) of
310 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
316 floatTy = mkTyConTy floatTyCon
318 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [] [floatDataCon]
319 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
321 isFloatTy :: Type -> Bool
323 = case (splitAlgTyConApp_maybe ty) of
324 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
330 doubleTy = mkTyConTy doubleTyCon
332 isDoubleTy :: Type -> Bool
334 = case (splitAlgTyConApp_maybe ty) of
335 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
338 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [] [doubleDataCon]
339 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
344 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
345 alpha_tyvar [(True,False)] [stablePtrDataCon]
348 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
349 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
354 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
355 [] [] [foreignObjDataCon]
358 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
359 [] [] [foreignObjPrimTy] foreignObjTyCon
362 %************************************************************************
364 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
366 %************************************************************************
368 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
371 integerTy = mkTyConTy integerTyCon
373 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer")
374 [] [] [smallIntegerDataCon, largeIntegerDataCon]
376 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_BASE SLIT("S#")
377 [] [] [intPrimTy] integerTyCon
378 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_BASE SLIT("J#")
379 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
382 isIntegerTy :: Type -> Bool
384 = case (splitAlgTyConApp_maybe ty) of
385 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
390 %************************************************************************
392 \subsection[TysWiredIn-ext-type]{External types}
394 %************************************************************************
396 The compiler's foreign function interface supports the passing of a
397 restricted set of types as arguments and results (the restricting factor
401 isFFIArgumentTy :: Type -> Bool
403 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
404 case (splitAlgTyConApp_maybe ty) of
405 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
408 -- types that can be passed as arguments to "foreign" functions
410 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
411 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
412 , floatTyConKey, doubleTyConKey
413 , addrTyConKey, charTyConKey, foreignObjTyConKey
415 , byteArrayTyConKey, mutableByteArrayTyConKey
418 -- types that can be passed from the outside world into Haskell.
419 -- excludes (mutable) byteArrays.
420 isFFIExternalTy :: Type -> Bool
422 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
423 case (splitAlgTyConApp_maybe ty) of
424 Just (tycon, _, _) ->
426 u_tycon = getUnique tycon
428 (u_tycon `elem` primArgTyConKeys) &&
429 not (u_tycon `elem` notLegalExternalTyCons)
433 isFFIResultTy :: Type -> Bool
435 not (isUnLiftedType ty) &&
436 case (splitAlgTyConApp_maybe ty) of
437 Just (tycon, _, _) ->
439 u_tycon = getUnique tycon
441 (u_tycon == getUnique unitTyCon) ||
442 ((u_tycon `elem` primArgTyConKeys) &&
443 not (u_tycon `elem` notLegalExternalTyCons))
446 -- it's illegal to return foreign objects and (mutable)
447 -- bytearrays from a _ccall_ / foreign declaration
448 -- (or be passed them as arguments in foreign exported functions).
449 notLegalExternalTyCons =
450 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
454 %************************************************************************
456 \subsection[TysWiredIn-Bool]{The @Bool@ type}
458 %************************************************************************
460 An ordinary enumeration type, but deeply wired in. There are no
461 magical operations on @Bool@ (just the regular Prelude code).
463 {\em BEGIN IDLE SPECULATION BY SIMON}
465 This is not the only way to encode @Bool@. A more obvious coding makes
466 @Bool@ just a boxed up version of @Bool#@, like this:
469 data Bool = MkBool Bool#
472 Unfortunately, this doesn't correspond to what the Report says @Bool@
473 looks like! Furthermore, we get slightly less efficient code (I
474 think) with this coding. @gtInt@ would look like this:
477 gtInt :: Int -> Int -> Bool
478 gtInt x y = case x of I# x# ->
480 case (gtIntPrim x# y#) of
484 Notice that the result of the @gtIntPrim@ comparison has to be turned
485 into an integer (here called @b#@), and returned in a @MkBool@ box.
487 The @if@ expression would compile to this:
490 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
493 I think this code is a little less efficient than the previous code,
494 but I'm not certain. At all events, corresponding with the Report is
495 important. The interesting thing is that the language is expressive
496 enough to describe more than one alternative; and that a type doesn't
497 necessarily need to be a straightforwardly boxed version of its
498 primitive counterpart.
500 {\em END IDLE SPECULATION BY SIMON}
503 boolTy = mkTyConTy boolTyCon
505 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
506 pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
508 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
509 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
512 %************************************************************************
514 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
516 %************************************************************************
518 Special syntax, deeply wired in, but otherwise an ordinary algebraic
521 data [] a = [] | a : (List a)
523 data (,) a b = (,,) a b
528 mkListTy :: Type -> Type
529 mkListTy ty = mkTyConApp listTyCon [ty]
531 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
533 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
534 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
536 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
537 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
538 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
539 -- Interesting: polymorphic recursion would help here.
540 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
541 -- gets the over-specific type (Type -> Type)
544 %************************************************************************
546 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
548 %************************************************************************
550 The tuple types are definitely magic, because they form an infinite
555 They have a special family of type constructors, of type @TyCon@
556 These contain the tycon arity, but don't require a Unique.
559 They have a special family of constructors, of type
560 @Id@. Again these contain their arity but don't need a Unique.
563 There should be a magic way of generating the info tables and
564 entry code for all tuples.
566 But at the moment we just compile a Haskell source
567 file\srcloc{lib/prelude/...} containing declarations like:
570 data Tuple2 a b = Tup2 a b
571 data Tuple3 a b c = Tup3 a b c
572 data Tuple4 a b c d = Tup4 a b c d
575 The print-names associated with the magic @Id@s for tuple constructors
576 ``just happen'' to be the same as those generated by these
580 The instance environment should have a magic way to know
581 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
582 so on. \ToDo{Not implemented yet.}
585 There should also be a way to generate the appropriate code for each
586 of these instances, but (like the info tables and entry code) it is
587 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
591 mkTupleTy :: Int -> [Type] -> Type
592 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
594 mkUnboxedTupleTy :: Int -> [Type] -> Type
595 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
597 unitTy = mkTupleTy 0 []