The semantics of External Core rely on the contents and informal
semantics of the primitive module
ghc-prim:GHC.Prim. Nearly all
the primitives are required in order to cover GHC’s implementation
of the Haskell98 standard prelude; the only operators that can be
completely omitted are those supporting the byte-code interpreter,
parallelism, and foreign objects. Some of the concurrency
primitives are needed, but can be given degenerate implementations
if it desired to target a purely sequential backend (see Section
the Non-concurrent Back End section).
In addition to these primitives, a large number of C library functions are required to implement the full standard Prelude, particularly to handle I/O and arithmetic on less usual types.
For a full listing of the names and types of the primitive operators, see the GHC library documentation [ghcprim].
The Haskell98 standard prelude doesn’t include any concurrency support, but GHC’s implementation of it relies on the existence of some concurrency primitives. However, it never actually forks multiple threads. Hence, the concurrency primitives can be given degenerate implementations that will work in a non-concurrent setting, as follows:
ThreadIdzhcan be represented by a singleton type, whose (unique) value is returned by
forkzhcan just die with an “unimplemented” message.
yieldzhcan also just die “unimplemented” since in a one-thread world, the only thread a thread can kill is itself, and if a thread yields the program hangs.
MVarzh acan be represented by
MutVarzh (Maybe a); where a concurrent implementation would block, the sequential implementation can just die with a suitable message (since no other thread exists to unblock it).
waitWritezhcan be implemented using a
selectwith no timeout.
Only the following combination of literal forms and types are permitted:
|Unicode character code|
|character||Unicode character specified by ASCII character|
|string||Address of specified C-format string|