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:
ThreadIdzh can be represented by a singleton type, whose
(unique) value is returned by
forkzh can just die with an “unimplemented” message.
yieldzh can 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 a can 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).
waitWritezh can be implemented using a
with no timeout.
Only the following combination of literal forms and types are permitted:
|Unicode character code
|Unicode character specified by ASCII character
|Address of specified C-format string