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.
- data Sink a
- newSinkMsg :: String -> IO (Sink a, a)
- newSink :: IO (Sink a, a)
- tryWriteSink :: Sink a -> a -> IO Bool
- writeSink :: Sink a -> a -> IO ()
- data MultipleWrites = MultipleWrites
Documentation
newSinkMsg :: String -> IO (Sink a, a)Source
tryWriteSink :: Sink a -> a -> IO BoolSource
writeSink :: Sink a -> a -> IO ()Source
Attempt to assign a value to a Sink. If the Sink had already
been written to, throw a MultipleWrites exception. This is an
atomic (thread safe) operation.
data MultipleWrites Source
Constructors
| MultipleWrites |