- Warning:* this module is internal. If you find that you need it
then please contact the maintainers and explain what you are trying to
do and discuss what you would need in the public API. It is important
that you do this as the module may not be exposed at all in future
releases.
 
Core types and functions for the 
Builder monoid and its
generalization, the 
Put monad.
The design of the 
Builder monoid is optimized such that
- buffers of arbitrary size can be filled as efficiently as possible
and
 
- sequencing of Builders is as cheap as possible.
 
We achieve (1) by completely handing over control over writing to the
buffer to the 
BuildStep implementing the 
Builder. This
BuildStep is just told the start and the end of the buffer
(represented as a 
BufferRange). Then, the 
BuildStep can
write to as big a prefix of this 
BufferRange in any way it
desires. If the 
BuildStep is done, the 
BufferRange is
full, or a long sequence of bytes should be inserted directly, then
the 
BuildStep signals this to its caller using a
BuildSignal.
We achieve (2) by requiring that every 
Builder is implemented
by a 
BuildStep that takes a continuation 
BuildStep,
which it calls with the updated 
BufferRange after it is done.
Therefore, only two pointers have to be passed in a function call to
implement concatenation of 
Builders. Moreover, many
Builders are completely inlined, which enables the compiler to
sequence them without a function call and with no boxing at all.
This design gives the implementation of a 
Builder full access
to the 
IO monad. Therefore, utmost care has to be taken to not
overwrite anything outside the given 
BufferRanges. Moreover,
further care has to be taken to ensure that 
Builders and
Puts are referentially transparent. See the comments of the
builder and 
put functions for further information. Note
that there are 
no safety belts at all, when implementing a
Builder using an 
IO action: you are writing code that
might enable the next buffer-overflow attack on a Haskell server!