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, 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] -> [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 cons
119 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
134 tycon = mkSynTyCon name kind arity tyvars expansion
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 name_str tycon
182 tc_kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
184 tuple_con = pcDataCon dc_uniq mod_name 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
191 unitTyCon = tupleTyCon 0
192 pairTyCon = tupleTyCon 2
194 unitDataCon = tupleCon 0
195 pairDataCon = tupleCon 2
198 %************************************************************************
200 \subsection[TysWiredIn-ubx-tuples]{Unboxed Tuple Types}
202 %************************************************************************
205 unboxedTupleTyCon :: Arity -> TyCon
206 unboxedTupleTyCon i | i > mAX_TUPLE_SIZE = fst (mk_unboxed_tuple i)
207 | otherwise = unboxedTupleTyConArr!i
209 unboxedTupleCon :: Arity -> DataCon
210 unboxedTupleCon i | i > mAX_TUPLE_SIZE = snd (mk_unboxed_tuple i)
211 | otherwise = unboxedTupleConArr!i
213 unboxedTupleTyConArr :: Array Int TyCon
214 unboxedTupleTyConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map fst ubx_tuples)
216 unboxedTupleConArr :: Array Int DataCon
217 unboxedTupleConArr = array (0,mAX_TUPLE_SIZE) ([0..] `zip` map snd ubx_tuples)
219 ubx_tuples :: [(TyCon,DataCon)]
220 ubx_tuples = [mk_unboxed_tuple i | i <- [0..mAX_TUPLE_SIZE]]
222 mk_unboxed_tuple :: Int -> (TyCon,DataCon)
223 mk_unboxed_tuple arity = (tycon, tuple_con)
225 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con False
226 tc_name = mkWiredInTyConName tc_uniq mod_name name_str tycon
227 tc_kind = mkArrowKinds (map tyVarKind tyvars) unboxedTypeKind
229 tuple_con = pcDataCon dc_uniq mod_name name_str tyvars [] tyvar_tys tycon
230 tyvars = take arity openAlphaTyVars
231 tyvar_tys = mkTyVarTys tyvars
232 (mod_name, name_str) = mkUbxTupNameStr arity
233 tc_uniq = mkUbxTupleTyConUnique arity
234 dc_uniq = mkUbxTupleDataConUnique arity
236 unboxedPairTyCon = unboxedTupleTyCon 2
237 unboxedPairDataCon = unboxedTupleCon 2
240 %************************************************************************
242 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
244 %************************************************************************
247 -- The Void type is represented as a data type with no constructors
248 -- It's a built in type (i.e. there's no way to define it in Haskell;
249 -- the nearest would be
251 -- data Void = -- No constructors!
253 -- ) It's boxed; there is only one value of this
254 -- type, namely "void", whose semantics is just bottom.
256 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
263 charTy = mkTyConTy charTyCon
265 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [charDataCon]
266 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
268 stringTy = mkListTy charTy -- convenience only
272 intTy = mkTyConTy intTyCon
274 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [intDataCon]
275 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
277 isIntTy :: Type -> Bool
279 = case (splitAlgTyConApp_maybe ty) of
280 Just (tycon, [], _) -> getUnique tycon == intTyConKey
283 inIntRange :: Integer -> Bool -- Tells if an integer lies in the legal range of Ints
284 inIntRange i = (min_int <= i) && (i <= max_int)
286 max_int, min_int :: Integer
287 max_int = toInteger maxInt
288 min_int = toInteger minInt
294 wordTy = mkTyConTy wordTyCon
296 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [wordDataCon]
297 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
301 addrTy = mkTyConTy addrTyCon
303 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [addrDataCon]
304 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
306 isAddrTy :: Type -> Bool
308 = case (splitAlgTyConApp_maybe ty) of
309 Just (tycon, [], _) -> getUnique tycon == addrTyConKey
315 floatTy = mkTyConTy floatTyCon
317 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_BASE SLIT("Float") [] [floatDataCon]
318 floatDataCon = pcDataCon floatDataConKey pREL_BASE SLIT("F#") [] [] [floatPrimTy] floatTyCon
320 isFloatTy :: Type -> Bool
322 = case (splitAlgTyConApp_maybe ty) of
323 Just (tycon, [], _) -> getUnique tycon == floatTyConKey
329 doubleTy = mkTyConTy doubleTyCon
331 isDoubleTy :: Type -> Bool
333 = case (splitAlgTyConApp_maybe ty) of
334 Just (tycon, [], _) -> getUnique tycon == doubleTyConKey
337 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_BASE SLIT("Double") [] [doubleDataCon]
338 doubleDataCon = pcDataCon doubleDataConKey pREL_BASE SLIT("D#") [] [] [doublePrimTy] doubleTyCon
343 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
344 alpha_tyvar [stablePtrDataCon]
347 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
348 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
353 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
354 [] [foreignObjDataCon]
357 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
358 [] [] [foreignObjPrimTy] foreignObjTyCon
361 %************************************************************************
363 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
365 %************************************************************************
367 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
370 integerTy = mkTyConTy integerTyCon
372 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_BASE SLIT("Integer") [] [smallIntegerDataCon, largeIntegerDataCon]
374 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_BASE SLIT("S#")
375 [] [] [intPrimTy] integerTyCon
376 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_BASE SLIT("J#")
377 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
380 isIntegerTy :: Type -> Bool
382 = case (splitAlgTyConApp_maybe ty) of
383 Just (tycon, [], _) -> getUnique tycon == integerTyConKey
388 %************************************************************************
390 \subsection[TysWiredIn-ext-type]{External types}
392 %************************************************************************
394 The compiler's foreign function interface supports the passing of a
395 restricted set of types as arguments and results (the restricting factor
399 isFFIArgumentTy :: Type -> Bool
401 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
402 case (splitAlgTyConApp_maybe ty) of
403 Just (tycon, _, _) -> (getUnique tycon) `elem` primArgTyConKeys
406 -- types that can be passed as arguments to "foreign" functions
408 = [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
409 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
410 , floatTyConKey, doubleTyConKey
411 , addrTyConKey, charTyConKey, foreignObjTyConKey
413 , byteArrayTyConKey, mutableByteArrayTyConKey
416 -- types that can be passed from the outside world into Haskell.
417 -- excludes (mutable) byteArrays.
418 isFFIExternalTy :: Type -> Bool
420 (opt_GlasgowExts && isUnLiftedType ty) || --leave out for now: maybeToBool (maybeBoxedPrimType ty))) ||
421 case (splitAlgTyConApp_maybe ty) of
422 Just (tycon, _, _) ->
424 u_tycon = getUnique tycon
426 (u_tycon `elem` primArgTyConKeys) &&
427 not (u_tycon `elem` notLegalExternalTyCons)
431 isFFIResultTy :: Type -> Bool
433 not (isUnLiftedType ty) &&
434 case (splitAlgTyConApp_maybe ty) of
435 Just (tycon, _, _) ->
437 u_tycon = getUnique tycon
439 (u_tycon == getUnique unitTyCon) ||
440 ((u_tycon `elem` primArgTyConKeys) &&
441 not (u_tycon `elem` notLegalExternalTyCons))
444 -- it's illegal to return foreign objects and (mutable)
445 -- bytearrays from a _ccall_ / foreign declaration
446 -- (or be passed them as arguments in foreign exported functions).
447 notLegalExternalTyCons =
448 [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
452 %************************************************************************
454 \subsection[TysWiredIn-Bool]{The @Bool@ type}
456 %************************************************************************
458 An ordinary enumeration type, but deeply wired in. There are no
459 magical operations on @Bool@ (just the regular Prelude code).
461 {\em BEGIN IDLE SPECULATION BY SIMON}
463 This is not the only way to encode @Bool@. A more obvious coding makes
464 @Bool@ just a boxed up version of @Bool#@, like this:
467 data Bool = MkBool Bool#
470 Unfortunately, this doesn't correspond to what the Report says @Bool@
471 looks like! Furthermore, we get slightly less efficient code (I
472 think) with this coding. @gtInt@ would look like this:
475 gtInt :: Int -> Int -> Bool
476 gtInt x y = case x of I# x# ->
478 case (gtIntPrim x# y#) of
482 Notice that the result of the @gtIntPrim@ comparison has to be turned
483 into an integer (here called @b#@), and returned in a @MkBool@ box.
485 The @if@ expression would compile to this:
488 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
491 I think this code is a little less efficient than the previous code,
492 but I'm not certain. At all events, corresponding with the Report is
493 important. The interesting thing is that the language is expressive
494 enough to describe more than one alternative; and that a type doesn't
495 necessarily need to be a straightforwardly boxed version of its
496 primitive counterpart.
498 {\em END IDLE SPECULATION BY SIMON}
501 boolTy = mkTyConTy boolTyCon
503 boolTyCon = pcTyCon EnumType NonRecursive boolTyConKey
504 pREL_BASE SLIT("Bool") [] [falseDataCon, trueDataCon]
506 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
507 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
510 %************************************************************************
512 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
514 %************************************************************************
516 Special syntax, deeply wired in, but otherwise an ordinary algebraic
519 data [] a = [] | a : (List a)
521 data (,) a b = (,,) a b
526 mkListTy :: Type -> Type
527 mkListTy ty = mkTyConApp listTyCon [ty]
529 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
531 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
532 alpha_tyvar [nilDataCon, consDataCon]
534 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
535 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
536 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
537 -- Interesting: polymorphic recursion would help here.
538 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
539 -- gets the over-specific type (Type -> Type)
542 %************************************************************************
544 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
546 %************************************************************************
548 The tuple types are definitely magic, because they form an infinite
553 They have a special family of type constructors, of type @TyCon@
554 These contain the tycon arity, but don't require a Unique.
557 They have a special family of constructors, of type
558 @Id@. Again these contain their arity but don't need a Unique.
561 There should be a magic way of generating the info tables and
562 entry code for all tuples.
564 But at the moment we just compile a Haskell source
565 file\srcloc{lib/prelude/...} containing declarations like:
568 data Tuple2 a b = Tup2 a b
569 data Tuple3 a b c = Tup3 a b c
570 data Tuple4 a b c d = Tup4 a b c d
573 The print-names associated with the magic @Id@s for tuple constructors
574 ``just happen'' to be the same as those generated by these
578 The instance environment should have a magic way to know
579 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
580 so on. \ToDo{Not implemented yet.}
583 There should also be a way to generate the appropriate code for each
584 of these instances, but (like the info tables and entry code) it is
585 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
589 mkTupleTy :: Int -> [Type] -> Type
590 mkTupleTy arity tys = mkTyConApp (tupleTyCon arity) tys
592 mkUnboxedTupleTy :: Int -> [Type] -> Type
593 mkUnboxedTupleTy arity tys = mkTyConApp (unboxedTupleTyCon arity) tys
595 unitTy = mkTupleTy 0 []