procrastinating-structure-1.0.1: Pure structures that can be incrementally created
in impure code

Data.PVar.Structure

Description

This module provides the Structure type class, enabling you to
create a pure data structure, which is available immediately, and
then gradually fill it in using the IO monad. This means that you
can go ahead and start using the structure before it is fully
defined. If a part of the structure is evaluated before it has been
written then that part is treated as _|_. This is technically more
pure than values from unsafeInterleaveIO. Evaluating the
structure, even before it is defined, doesn't perform any IO. All
the IO happens in the IO monad.

Here is an example of creating a list of Ints and then writing
each level of it step by step. The returned result is [5].

foo :: IO [Int]
foo = do
-- Create the pure list and the handle for writing to it.
(pxs, xs) <- newStruc
-- Write the cons constructor to the list. This gives us handles
-- for writing the head and tail of the list.
Just (h, t) <- writeStruc pxs ConsC
-- Write the head of the list.
writeStruc h 5
-- Write the tail of the list. This finishes it.
writeStruc t NilC
-- Get rid of the Value wrapper on the list's value and return
-- the resulting list.
return $ map getValue xs

Documentation

A structure type is one which represents any lazy data
structure. With the exception of the Value newtype wrapper, there
is little reason to define an instance of Structure for completely
strict types. This is because the entire thing must be defined at
once anyway, so you might as well just use a PVar.