sink-0.1.0.1: An alternative to lazy I/O that doesn't conflate
execution with evaluation

Data.Sink

Description

Sinks are a more flexible alternative to lazy I/O
(unsafeInterleaveIO). Lazy I/O conflates evaluation with execution;
a value obtained from unsafeInterleaveIO can perform side-effects
during the evaluation of pure code. Like lazy I/O, a Sink provides a
way to obtain the value of the result of an IO action before the
action has been executed, but unlike lazy I/O, it does not enable pure
code to perform side-effects. Instead, the value is explicitly
assigned by a later IO action; repeated attempts to assign the value
of a Sink fail. The catch is that this explicit assignment must
occur before the value is forced, so just like with lazy I/O, you
can't get away with completely ignoring evaluation order without
introducing bugs. However, violating this condition does not violate
purity because if the value is forced before it has been assigned, it
is .

In practice, using Sinks instead of unsafeInterleaveIO requires a
bit more IO boilerplate. The main practical difference is that while
unsafeInterleaveIO requires you to reason about effects from the
point of view of pure code, Sinks require you to reason about
evaluation order of pure code from the point of view of IO; the IO
portion of your program will have to be aware of what data is
necessary to produce *for* your pure code in order to be able to
consume the output it expects *from* your pure code.

Documentation

Create a new Sink and a pure value. If you force the value
before writing to the Sink, the value is . If you write to the
Sink before forcing the value, the value will be whatever you
wrote to the Sink. The String argument is an error message in
case you force the value before writing to the Sink.