+PrelGHC module
-This section defines all the types which are primitive in Glasgow
+This module defines all the types which are primitive in Glasgow
Haskell, and the operations provided for them.
A primitive type is one which cannot be defined in Haskell, and which
is therefore built into the language and compiler. Primitive types
-are always unboxed; that is, a value of primitive type cannot be
-bottom.
+are always unlifted; that is, a value of primitive type cannot be
+bottom. We use the convention that primitive types, values, and
+operations have a @#@ suffix.
Primitive values are often represented by a simple bit-pattern, such
as @Int#@, @Float#@, @Double#@. But this is not necessarily the case:
a primitive value might be represented by a pointer to a
heap-allocated object. Examples include @Array#@, the type of
-primitive arrays. You might think this odd: doesn't being
-heap-allocated mean that it has a box? No, it does not. A primitive
-array is heap-allocated because it is too big a value to fit in a
-register, and would be too expensive to copy around; in a sense, it is
-accidental that it is represented by a pointer. If a pointer
-represents a primitive value, then it really does point to that value:
-no unevaluated thunks, no indirections...nothing can be at the other
-end of the pointer than the primitive value.
-
-This section also describes a few non-primitive types, which are needed
-to express the result types of some primitive operations.
+primitive arrays. A primitive array is heap-allocated because it is
+too big a value to fit in a register, and would be too expensive to
+copy around; in a sense, it is accidental that it is represented by a
+pointer. If a pointer represents a primitive value, then it really
+does point to that value: no unevaluated thunks, no
+indirections...nothing can be at the other end of the pointer than the
+primitive value.
+
+Unboxed Tuples
+
+
+
+Unboxed tuples aren't really exported by @PrelGHC@, they're available
+by default with @-fglasgow-exts@. An unboxed tuple looks like this:
+
+
+(# e_1, ..., e_n #)
+
+
+where @e_1..e_n@ are expressions of any type (primitive or
+non-primitive). The type of an unboxed tuple looks the same.
+
+Unboxed tuples are used for functions that need to return multiple
+values, but they avoid the heap allocation normally associated with
+using fully-fledged tuples. When an unboxed tuple is returned, the
+components are put directly into registers or on the stack; the
+unboxed tuple itself does not have a composite representation. Many
+of the primitive operations listed in this section return unboxed
+tuples.
+
+There are some pretty stringent restrictions on the use of unboxed tuples:
+
+
+
+- Unboxed tuple types are subject to the same restrictions as
+other unboxed types; i.e. they may not be stored in polymorphic data
+structures or passed to polymorphic functions.
+
+
- Unboxed tuples may only be constructed as the direct result of
+a function, and may only be deconstructed with a @case@ expression.
+eg. the following are valid:
+
+
+f x y = (# x+1, y-1 #)
+g x = case f x x of { (# a, b #) -> a + b }
+
+
+but the following are invalid:
+
+
+f x y = g (# x, y #)
+g (# x, y #) = x + y
+
+
+- No variable can have an unboxed tuple type. This is illegal:
+
+
+f :: (# Int, Int #) -> (# Int, Int #)
+f x = x
+
+
+because @x@ has an unboxed tuple type.
+
+
+
+Note: we may relax some of these restrictions in the future.
+
+The @IO@ and @ST@ monads use unboxed tuples to avoid unnecessary
+allocation during sequences of operations.
Character and numeric types
@@ -104,7 +165,7 @@ type Double#
Double#
If you really want to know their exact equivalents in C, see
-@ghc/includes/StgTypes.lh@ in the GHC source tree.
+@ghc/includes/StgTypes.h@ in the GHC source tree.
Literals for these types may be written as follows:
@@ -145,7 +206,7 @@ Literals for these types may be written as follows:
Primitive-character operations
-characters, primitive
+characters, primitive operations
operators, primitive character
@@ -158,7 +219,7 @@ chr# :: Int# -> Char#
Primitive-@Int@ operations
-integers, primitive
+integers, primitive operations
operators, primitive integer
@@ -272,16 +333,13 @@ decodeDouble# :: Double# -> PrelNum.ReturnIntAndGMP
(And the same for @Float#@s.)
Operations on/for @Integers@ (interface to GMP)
-
+
arbitrary precision integers
Integer, operations on
We implement @Integers@ (arbitrary-precision integers) using the GNU
-multiple-precision (GMP) package (version 1.3.2).
-
-Note: some of this might change when we upgrade to using
-GMP~2.x.
+multiple-precision (GMP) package (version 2.0.2).
The data type for @Integer@ must mirror that for @MP_INT@ in @gmp.h@
(see @gmp.info@ in @ghc/includes/runtime/gmp@). It comes out as:
@@ -294,18 +352,6 @@ data Integer = J# Int# Int# ByteArray#
So, @Integer@ is really just a ``pairing'' type for a particular
collection of primitive types.
-The operations in the GMP return other combinations of
-GMP-plus-something, so we need ``pairing'' types for those, too:
-
-
-data Return2GMPs = Return2GMPs Int# Int# ByteArray# Int# Int# ByteArray#
-data ReturnIntAndGMP = ReturnIntAndGMP Int# Int# Int# ByteArray#
-
--- ????? something to return a string of bytes (in the heap?)
-
-Return2GMPs
-ReturnIntAndGMP
-
The primitive ops to support @Integers@ use the ``pieces'' of the
representation, and are as follows:
@@ -377,8 +423,8 @@ quotWord#, remWord# :: Word# -> Word# -> Word#
not# :: Word# -> Word#
-shiftL#, shiftRL# :: Word# -> Int# -> Word#
- -- shift left, right logical
+shiftL#, shiftRA#, shiftRL# :: Word# -> Int# -> Word#
+ -- shift left, right arithmetic, right logical
int2Word# :: Int# -> Word# -- just a cast, really
word2Int# :: Word# -> Int#
@@ -391,6 +437,7 @@ word2Int# :: Word# -> Int#
quotWord#
remWord#
shiftL#
+shiftRA#
shiftRL#
int2Word#
word2Int#
@@ -516,10 +563,11 @@ objects, because the result is simply the boxed object. So presumably
it should be entered --- we never usually return an unevaluated
object! This is a pain: primitive ops aren't supposed to do
complicated things like enter objects. The current solution is to
-return a lifted value, but I don't like it!
+return a single element unboxed tuple (see Section [).
]
-indexArray# :: Array# elt -> Int# -> PrelBase.Lift elt -- Yuk!
+indexArray# :: Array# elt -> Int# -> (# elt #)
indexArray#
@@ -544,7 +592,7 @@ type State# s
The type @GHC.RealWorld@ is truly opaque: there are no values defined
of this type, and no operations over it. It is ``primitive'' in that
-sense - but it is not unboxed! Its only role in life is to be
+sense - but it is not unlifted! Its only role in life is to be
the type which distinguishes the @IO@ state transformer.
@@ -557,44 +605,13 @@ data RealWorld
A single, primitive, value of type @State# RealWorld@ is provided.
-realWorld# :: State# GHC.RealWorld
+realWorld# :: State# RealWorld
realWorld# state object
(Note: in the compiler, not a @PrimOp@; just a mucho magic
@Id@. Exported from @GHC@, though).
-State pairing types
-
-
-
-This subsection defines some types which, while they aren't quite
-primitive because we can define them in Haskell, are very nearly so.
-They define constructors which pair a primitive state with a value of
-each primitive type. They are required to express the result type of
-the primitive operations in the state monad.
-
-data StateAndPtr# s elt = StateAndPtr# (State# s) elt
-
-data StateAndChar# s = StateAndChar# (State# s) Char#
-data StateAndInt# s = StateAndInt# (State# s) Int#
-data StateAndWord# s = StateAndWord# (State# s) Word#
-data StateAndFloat# s = StateAndFloat# (State# s) Float#
-data StateAndDouble# s = StateAndDouble# (State# s) Double#
-data StateAndAddr# s = StateAndAddr# (State# s) Addr#
-
-data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
-data StateAndForeignObj# s = StateAndForeignObj# (State# s) ForeignObj#
-data StateAndSynchVar# s a = StateAndSynchVar# (State# s) (SynchVar# a)
-
-data StateAndArray# s elt = StateAndArray# (State# s) (Array# elt)
-data StateAndMutableArray# s elt = StateAndMutableArray# (State# s) (MutableArray# s elt)
-data StateAndByteArray# s = StateAndByteArray# (State# s) ByteArray#
-data StateAndMutableByteArray# s = StateAndMutableByteArray# (State# s) (MutableByteArray# s)
-
-
-Hideous.
-
Mutable arrays
@@ -624,13 +641,13 @@ the array-allocation primitive. Reason: only the pointer case has to
worry about GC striking with a partly-initialised array.
-newArray# :: Int# -> elt -> State# s -> StateAndMutableArray# s elt
+newArray# :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #)
-newCharArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newIntArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newAddrArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newFloatArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newDoubleArray# :: Int# -> State# s -> StateAndMutableByteArray# s
+newCharArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newIntArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newAddrArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newFloatArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newDoubleArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
newArray#
newCharArray#
@@ -646,12 +663,12 @@ The size of a @ByteArray#@ is given in bytes.
arrays, reading and writing
-readArray# :: MutableArray# s elt -> Int# -> State# s -> StateAndPtr# s elt
-readCharArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndChar# s
-readIntArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndInt# s
-readAddrArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndAddr# s
-readFloatArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndFloat# s
-readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndDouble# s
+readArray# :: MutableArray# s elt -> Int# -> State# s -> (# State# s, elt #)
+readCharArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
+readIntArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+readAddrArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
+readFloatArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
+readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
writeArray# :: MutableArray# s elt -> Int# -> elt -> State# s -> State# s
writeCharArray# :: MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
@@ -698,8 +715,8 @@ Only unsafe-freeze has a primitive. (Safe freeze is done directly in Haskell
by copying the array and then using @unsafeFreeze@.)
-unsafeFreezeArray# :: MutableArray# s elt -> State# s -> StateAndArray# s elt
-unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> StateAndByteArray# s
+unsafeFreezeArray# :: MutableArray# s elt -> State# s -> (# State# s, Array# s elt #)
+unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
unsafeFreezeArray#
unsafeFreezeByteArray#
@@ -732,9 +749,9 @@ we don't allocate one twice by accident, and then only free one of the
copies.
-makeStablePointer# :: a -> State# RealWorld -> StateAndStablePtr# RealWorld a
+makeStablePointer# :: a -> State# RealWorld -> (# State# RealWord, StablePtr# a #)
freeStablePointer# :: StablePtr# a -> State# RealWorld -> State# RealWorld
-deRefStablePointer# :: StablePtr# a -> State# RealWorld -> StateAndPtr RealWorld a
+deRefStablePointer# :: StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #)
makeStablePointer#
freeStablePointer#
@@ -772,7 +789,7 @@ GHC provides two primitives on @ForeignObj#@:
makeForeignObj#
:: Addr# -- foreign reference
-> Addr# -- pointer to finalisation routine
- -> StateAndForeignObj# RealWorld ForeignObj#
+ -> (# State# RealWorld, ForeignObj# )
writeForeignObj
:: ForeignObj# -- foreign object
-> Addr# -- datum
@@ -796,10 +813,10 @@ Concurrent Haskell's MVars (see the Concurrent Haskell paper for
the operational behaviour of these operations).
-type SynchVar# s elt -- primitive
+type MVar# s elt -- primitive
-newSynchVar#:: State# s -> StateAndSynchVar# s elt
-takeMVar# :: SynchVar# s elt -> State# s -> StateAndPtr# s elt
+newMVar# :: State# s -> (# State# s, MVar# s elt #)
+takeMVar# :: SynchVar# s elt -> State# s -> (# State# s, elt #)
putMVar# :: SynchVar# s elt -> State# s -> State# s
SynchVar#
@@ -807,25 +824,6 @@ putMVar# :: SynchVar# s elt -> State# s -> State# s
takeMVar
putMVar
-@spark#@ primitive operation (for parallel execution)
-
-spark primitive operation
-
-ToDo: say something It's used in the unfolding for @par@.
-
-The @errorIO#@ primitive operation
-
-errors, primitive
-
-The @errorIO#@ primitive takes an argument much like @IO@. It aborts
-execution of the current program, and continues instead by performing
-the given @IO@-like value on the current state of the world.
-
-
-errorIO# :: (State# RealWorld# -> a) -> a
-
-errorIO#
-
GHC/Hugs Extension Libraries
@@ -897,27 +895,27 @@ newAddrArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
newIntArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
newFloatArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
newDoubleArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
-
+
boundsOfArray :: Ix ix => MutableArray s ix elt -> (ix, ix)
boundsOfByteArray :: Ix ix => MutableByteArray s ix -> (ix, ix)
-
-
-readArray :: Ix ix => MutableArray s ix elt -> ix -> ST s elt
-
+
+
+readArray :: Ix ix => MutableArray s ix elt -> ix -> ST s elt
+
readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
readAddrArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Addr
readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
-
-writeArray :: Ix ix => MutableArray s ix elt -> ix -> elt -> ST s ()
+
+writeArray :: Ix ix => MutableArray s ix elt -> ix -> elt -> ST s ()
writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
writeAddrArray :: Ix ix => MutableByteArray s ix -> ix -> Addr -> ST s ()
writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
-
-freezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
+
+freezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
freezeCharArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
freezeIntArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
freezeAddrArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
@@ -929,7 +927,35 @@ unsafeFreezeByteArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
thawArray :: Ix ix => Array ix elt -> ST s (MutableArray s ix elt)
-%ToDo: index these.
+newArray
+newCharArray
+newAddrArray
+newIntArray
+newFloatArray
+newDoubleArray
+boundsOfArray
+boundsOfByteArray
+readArray
+readCharArray
+readIntArray
+readAddrArray
+readFloatArray
+readDoubleArray
+writeArray
+writeCharArray
+writeIntArray
+writeAddrArray
+writeFloatArray
+writeDoubleArray
+freezeArray
+freezeCharArray
+freezeIntArray
+freezeAddrArray
+freezeFloatArray
+freezeDoubleArray
+unsafeFreezeArray
+unsafeFreezeByteArray
+thawArray
The @ByteArray@ interface