The GHC prelude and libraries This document describes GHC's prelude and libraries. The basic story is that of the Haskell 1.4 Report and Libraries document (which we do not reproduce here), but this document describes in addition: GHC's additional non-standard libraries and types, such as state transformers, packed strings, foreign objects, stable pointers, and so on. GHC's primitive types and operations. The standard Haskell functions are implemented on top of these, and it is sometimes useful to use them directly. The organisation of these libraries into directories. Short description of programmer interface to the non-standard libraries provided in addition to the standard prelude. A number of the libraries that provide access to GHC's language extensions are shared by Hugs, and are described in the GHC/Hugs Extension Libraries document. Prelude extensions GHC's prelude contains the following non-standard extensions: fromInt method in class Num: It's there. Converts from an Int to the type. toInt method in class Integral: Converts from Integral type to an Int. GHC also internally uses a number of modules that begin with the string PrelPrel module prefix: for this reason, we don't recommend that you use any module names beginning with Prel in your own programs. The Prel modules are always available: in fact, you can get access to several extensions this way (for some you might need to give the -fglasgow-exts option flag). GHC/Hugs Extension Libraries The extension libraries provided by both GHC and Hugs are described in the GHC/Hugs Extension Library Document GHC-only Extension Libraries libraries, ghc-only extension libraries, ghc-only If you rely on the implicit import Prelude that GHC normally does for you, and if you don't use any weird flags (notably ), and if you don't import the Glasgow extensions interface, GlaExts, then GHC should work exactly as the Haskell report says (modulo a few minor issues, see ). If you turn on , a new world opesn up to you and the compiler will recognise and parse unboxed values properly, and provide access to the various interfaces libraries described here (and piles of other goodies.) &mutablearray &bytearray The <Literal>CCall</Literal> module The CCall module defines the classes CCallable and CReturnable, along with instances for the primitive types (Int, Int#, Float, Float# etc.) GHC knows to import this module if you use _ccall_, but if you need to define your own instances of these classes, you will need to import CCall explicitly. More information on how to use _ccall_ can be found in . The <Literal>GlaExts</Literal> interface GlaExts interface (GHC extensions) The GlaExts interface provides access to extensions that only GHC implements. These currently are: unboxed types, including the representations of the primitive types (Int, Float, etc.), and the GHC primitive operations (+#, ==#, etc.). This module used to provide access to all the Glasgow extensions, but these have since been moved into separate libraries for compatibility with Hugs (version 2.09: in fact, you can still get at this stuff via GlaExts for compatibility, but this facility will likely be removed in the future). -- the representation of some basic types: data Char = C# Char# data Int = I# Int# data Addr = A# Addr# data Word = W# Word# data Float = F# Float# data Double = D# Double# data Integer = S# Int# -- small integers | J# Int# ByteArray# -- large integers module GHC -- all primops and primitive types. The module <Literal>PrelGHC</Literal>: really primitive stuff PrelGHC module 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 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. 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 . 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 character types, primitive numeric types, primitive integer types, primitive floating point types, primitive There are the following obvious primitive types: type Char# type Int# -- see also Word# and Addr#, later type Float# type Double# Char# Int# Float# Double# If you really want to know their exact equivalents in C, see ghc/includes/StgTypes.h in the GHC source tree. Literals for these types may be written as follows: 1# an Int# 1.2# a Float# 1.34## a Double# 'a'# a Char#; for weird characters, use '\o<octal>'# "a"# an Addr# (a `char *') literals, primitive constants, primitive numbers, primitive Comparison operations comparisons, primitive operators, comparison {>,>=,==,/=,<,<=}# :: Int# -> Int# -> Bool {gt,ge,eq,ne,lt,le}Char# :: Char# -> Char# -> Bool -- ditto for Word# and Addr# ># >=# ==# /=# <# <=# gt{Char,Word,Addr}# ge{Char,Word,Addr}# eq{Char,Word,Addr}# ne{Char,Word,Addr}# lt{Char,Word,Addr}# le{Char,Word,Addr}# Primitive-character operations characters, primitive operations operators, primitive character ord# :: Char# -> Int# chr# :: Int# -> Char# ord# chr# Primitive-<Literal>Int</Literal> operations integers, primitive operations operators, primitive integer {+,-,*,quotInt,remInt}# :: Int# -> Int# -> Int# negateInt# :: Int# -> Int# iShiftL#, iShiftRA#, iShiftRL# :: Int# -> Int# -> Int# -- shift left, right arithmetic, right logical +# -# *# quotInt# remInt# iShiftL# iShiftRA# iShiftRL# shift operations, integer Note: No error/overflow checking! Primitive-<Literal>Double</Literal> and <Literal>Float</Literal> operations floating point numbers, primitive operators, primitive floating point {+,-,*,/}## :: Double# -> Double# -> Double# {<,<=,==,/=,>=,>}## :: Double# -> Double# -> Bool negateDouble# :: Double# -> Double# double2Int# :: Double# -> Int# int2Double# :: Int# -> Double# {plus,minux,times,divide}Float# :: Float# -> Float# -> Float# {gt,ge,eq,ne,lt,le}Float# :: Float# -> Float# -> Bool negateFloat# :: Float# -> Float# float2Int# :: Float# -> Int# int2Float# :: Int# -> Float# +## -## *## /## <## <=## ==## =/## >=## >## negateDouble# double2Int# int2Double# plusFloat# minusFloat# timesFloat# divideFloat# gtFloat# geFloat# eqFloat# neFloat# ltFloat# leFloat# negateFloat# float2Int# int2Float# And a full complement of trigonometric functions: expDouble# :: Double# -> Double# logDouble# :: Double# -> Double# sqrtDouble# :: Double# -> Double# sinDouble# :: Double# -> Double# cosDouble# :: Double# -> Double# tanDouble# :: Double# -> Double# asinDouble# :: Double# -> Double# acosDouble# :: Double# -> Double# atanDouble# :: Double# -> Double# sinhDouble# :: Double# -> Double# coshDouble# :: Double# -> Double# tanhDouble# :: Double# -> Double# powerDouble# :: Double# -> Double# -> Double# trigonometric functions, primitive similarly for Float#. There are two coercion functions for Float#/Double#: float2Double# :: Float# -> Double# double2Float# :: Double# -> Float# float2Double# double2Float# The primitive versions of encodeDouble/decodeDouble: encodeDouble# :: Int# -> Int# -> ByteArray# -- Integer mantissa -> Int# -- Int exponent -> Double# decodeDouble# :: Double# -> PrelNum.ReturnIntAndGMP encodeDouble# decodeDouble# (And the same for Float#s.) Operations on/for <Literal>Integers</Literal> (interface to GMP) arbitrary precision integers Integer, operations on We implement Integers (arbitrary-precision integers) using the GNU multiple-precision (GMP) package (version 2.0.2). The data type for Integer is either a small integer, represented by an Int, or a large integer represented using the pieces required by GMP's MP_INT in gmp.h (see gmp.info in ghc/includes/runtime/gmp). It comes out as: data Integer = S# Int# -- small integers | J# Int# ByteArray# -- large integers Integer type The primitive ops to support large Integers use the ``pieces'' of the representation, and are as follows: negateInteger# :: Int# -> ByteArray# -> Integer {plus,minus,times}Integer# :: Int# -> ByteArray# -> Int# -> ByteArray# -> Integer cmpInteger# :: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -- -1 for <; 0 for ==; +1 for > divModInteger#, quotRemInteger# :: Int# -> ByteArray# -> Int# -> ByteArray# -> PrelNum.Return2GMPs integer2Int# :: Int# -> ByteArray# -> Int# int2Integer# :: Int# -> Integer -- NB: no error-checking on these two! word2Integer# :: Word# -> Integer addr2Integer# :: Addr# -> Integer -- the Addr# is taken to be a `char *' string -- to be converted into an Integer. negateInteger# plusInteger# minusInteger# timesInteger# cmpInteger# divModInteger# quotRemInteger# integer2Int# int2Integer# word2Integer# addr2Integer# Words and addresses word, primitive type address, primitive type unsigned integer, primitive type pointer, primitive type A Word# is used for bit-twiddling operations. It is the same size as an Int#, but has no sign nor any arithmetic operations. type Word# -- Same size/etc as Int# but *unsigned* type Addr# -- A pointer from outside the "Haskell world" (from C, probably); -- described under "arrays" Word# Addr# Word#s and Addr#s have the usual comparison operations. Other unboxed-Word ops (bit-twiddling and coercions): and#, or#, xor# :: Word# -> Word# -> Word# -- standard bit ops. quotWord#, remWord# :: Word# -> Word# -> Word# -- word (i.e. unsigned) versions are different from int -- versions, so we have to provide these explicitly. not# :: Word# -> Word# shiftL#, shiftRA#, shiftRL# :: Word# -> Int# -> Word# -- shift left, right arithmetic, right logical int2Word# :: Int# -> Word# -- just a cast, really word2Int# :: Word# -> Int# bit operations, Word and Addr and# or# xor# not# quotWord# remWord# shiftL# shiftRA# shiftRL# int2Word# word2Int# Unboxed-Addr ops (C casts, really): int2Addr# :: Int# -> Addr# addr2Int# :: Addr# -> Int# int2Addr# addr2Int# The casts between Int#, Word# and Addr# correspond to null operations at the machine level, but are required to keep the Haskell type checker happy. Operations for indexing off of C pointers (Addr#s) to snatch values are listed under ``arrays''. Arrays arrays, primitive The type Array# elt is the type of primitive, unpointed arrays of values of type elt. type Array# elt Array# Array# is more primitive than a Haskell array—indeed, the Haskell Array interface is implemented using Array#—in that an Array# is indexed only by Int#s, starting at zero. It is also more primitive by virtue of being unboxed. That doesn't mean that it isn't a heap-allocated object—of course, it is. Rather, being unboxed means that it is represented by a pointer to the array itself, and not to a thunk which will evaluate to the array (or to bottom). The components of an Array# are themselves boxed. The type ByteArray# is similar to Array#, except that it contains just a string of (non-pointer) bytes. type ByteArray# ByteArray# Arrays of these types are useful when a Haskell program wishes to construct a value to pass to a C procedure. It is also possible to use them to build (say) arrays of unboxed characters for internal use in a Haskell program. Given these uses, ByteArray# is deliberately a bit vague about the type of its components. Operations are provided to extract values of type Char#, Int#, Float#, Double#, and Addr# from arbitrary offsets within a ByteArray#. (For type Foo#, the $i$th offset gets you the $i$th Foo#, not the Foo# at byte-position $i$. Mumble.) (If you want a Word#, grab an Int#, then coerce it.) Lastly, we have static byte-arrays, of type Addr# [mentioned previously]. (Remember the duality between arrays and pointers in C.) Arrays of this types are represented by a pointer to an array in the world outside Haskell, so this pointer is not followed by the garbage collector. In other respects they are just like ByteArray#. They are only needed in order to pass values from C to Haskell. Reading and writing Primitive arrays are linear, and indexed starting at zero. The size and indices of a ByteArray#, Addr#, and MutableByteArray# are all in bytes. It's up to the program to calculate the correct byte offset from the start of the array. This allows a ByteArray# to contain a mixture of values of different type, which is often needed when preparing data for and unpicking results from C. (Umm…not true of indices…WDP 95/09) Should we provide some sizeOfDouble# constants? Out-of-range errors on indexing should be caught by the code which uses the primitive operation; the primitive operations themselves do not check for out-of-range indexes. The intention is that the primitive ops compile to one machine instruction or thereabouts. We use the terms ``reading'' and ``writing'' to refer to accessing mutable arrays (see ), and ``indexing'' to refer to reading a value from an immutable array. Immutable byte arrays are straightforward to index (all indices in bytes): indexCharArray# :: ByteArray# -> Int# -> Char# indexIntArray# :: ByteArray# -> Int# -> Int# indexAddrArray# :: ByteArray# -> Int# -> Addr# indexFloatArray# :: ByteArray# -> Int# -> Float# indexDoubleArray# :: ByteArray# -> Int# -> Double# indexCharOffAddr# :: Addr# -> Int# -> Char# indexIntOffAddr# :: Addr# -> Int# -> Int# indexFloatOffAddr# :: Addr# -> Int# -> Float# indexDoubleOffAddr# :: Addr# -> Int# -> Double# indexAddrOffAddr# :: Addr# -> Int# -> Addr# -- Get an Addr# from an Addr# offset indexCharArray# indexIntArray# indexAddrArray# indexFloatArray# indexDoubleArray# indexCharOffAddr# indexIntOffAddr# indexFloatOffAddr# indexDoubleOffAddr# indexAddrOffAddr# The last of these, indexAddrOffAddr#, extracts an Addr# using an offset from another Addr#, thereby providing the ability to follow a chain of C pointers. Something a bit more interesting goes on when indexing arrays of boxed 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 single element unboxed tuple (see ). indexArray# :: Array# elt -> Int# -> (# elt #) indexArray# The state type state, primitive type State# The primitive type State# represents the state of a state transformer. It is parameterised on the desired type of state, which serves to keep states from distinct threads distinct from one another. But the only effect of this parameterisation is in the type system: all values of type State# are represented in the same way. Indeed, they are all represented by nothing at all! The code generator ``knows'' to generate no code, and allocate no registers etc, for primitive states. 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 unlifted! Its only role in life is to be the type which distinguishes the IO state transformer. data RealWorld State of the world A single, primitive, value of type State# RealWorld is provided. realWorld# :: State# RealWorld realWorld# state object (Note: in the compiler, not a PrimOp; just a mucho magic Id. Exported from GHC, though). Mutable arrays mutable arrays arrays, mutable Corresponding to Array# and ByteArray#, we have the types of mutable versions of each. In each case, the representation is a pointer to a suitable block of (mutable) heap-allocated storage. type MutableArray# s elt type MutableByteArray# s MutableArray# MutableByteArray# Allocation mutable arrays, allocation arrays, allocation allocation, of mutable arrays Mutable arrays can be allocated. Only pointer-arrays are initialised; arrays of non-pointers are filled in by ``user code'' rather than by 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 -> (# State# s, MutableArray# s elt #) 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# newIntArray# newAddrArray# newFloatArray# newDoubleArray# The size of a ByteArray# is given in bytes. Reading and writing arrays, reading and writing 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 writeIntArray# :: MutableByteArray# s -> Int# -> Int# -> State# s -> State# s writeAddrArray# :: MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s writeFloatArray# :: MutableByteArray# s -> Int# -> Float# -> State# s -> State# s writeDoubleArray# :: MutableByteArray# s -> Int# -> Double# -> State# s -> State# s readArray# readCharArray# readIntArray# readAddrArray# readFloatArray# readDoubleArray# writeArray# writeCharArray# writeIntArray# writeAddrArray# writeFloatArray# writeDoubleArray# Equality arrays, testing for equality One can take ``equality'' of mutable arrays. What is compared is the name or reference to the mutable array, not its contents. sameMutableArray# :: MutableArray# s elt -> MutableArray# s elt -> Bool sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Bool sameMutableArray# sameMutableByteArray# Freezing mutable arrays arrays, freezing mutable freezing mutable arrays mutable arrays, freezing 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 -> (# State# s, Array# s elt #) unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #) unsafeFreezeArray# unsafeFreezeByteArray# Stable pointers stable pointers pointers, stable A stable pointer is a name for a Haskell object which can be passed to the external world. It is ``stable'' in the sense that the name does not change when the Haskell garbage collector runs—in contrast to the address of the object which may well change. The stable pointer type is parameterised by the type of the thing which is named. type StablePtr# a StablePtr# A stable pointer is represented by an index into the (static) StablePointerTable. The Haskell garbage collector treats the StablePointerTable as a source of roots for GC. The makeStablePointer function converts a value into a stable pointer. It is part of the IO monad, because we want to be sure we don't allocate one twice by accident, and then only free one of the copies. makeStablePointer# :: a -> State# RealWorld -> (# State# RealWord, StablePtr# a #) freeStablePointer# :: StablePtr# a -> State# RealWorld -> State# RealWorld deRefStablePointer# :: StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) makeStablePointer# freeStablePointer# deRefStablePointer# There is also a C procedure FreeStablePtr which frees a stable pointer. Foreign objects Foreign objects A ForeignObj# is a reference to an object outside the Haskell world (i.e., from the C world, or a reference to an object on another machine completely.), where the Haskell world has been told ``Let me know when you're finished with this…''. type ForeignObj# ForeignObj# GHC provides two primitives on ForeignObj#: makeForeignObj# :: Addr# -- foreign reference -> Addr# -- pointer to finalisation routine -> (# State# RealWorld, ForeignObj# ) writeForeignObj :: ForeignObj# -- foreign object -> Addr# -- datum -> State# RealWorld -> State# RealWorld makeForeignObj# writeForeignObj# The module Foreign (see library documentation) provides a more programmer-friendly interface to foreign objects. Synchronizing variables (M-vars) synchronising variables (M-vars) M-Vars Synchronising variables are the primitive type used to implement Concurrent Haskell's MVars (see the Concurrent Haskell paper for the operational behaviour of these operations). type MVar# s elt -- primitive 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# newSynchVar# takeMVar putMVar &posix &libmisc