SafeCopy extends the parsing and serialization capabilities of Data.Serialize
to include nested version control. Nested version control means that you
can change the definition and binary format of a type nested deep within
other types without problems.

Consider this scenario. You want to store your contact list on disk
and so write the following code:

At this point, everything is fine. You get the awesome speed of Data.Serialize
together with Haskell's ease of use. However, things quickly take a U-turn for the worse
when you realize that you want to keep phone numbers as well as names and
addresses. Being the experienced coder that you are, you see that using a 3-tuple
isn't very pretty and you'd rather use a record. At first you fear that this
change in structure will invalidate all your old data. Those fears are quickly quelled,
though, when you remember how nifty SafeCopy is. With renewed enthusiasm,
you set out and write the following code:

The extension kind lets the system know that there is
at least one previous version of this type. A given data type
can only extend a single other data type. However, it is
perfectly fine to build chains of extensions. The migrations
between each step is handled automatically.

To ensure that no-one reads or writes values without handling versions
correct, it is necessary to restrict access to getCopy and putCopy.
This is where Contained enters the picture. It allows you to put
values in to a container but not to take them out again.

When serializing, we put a Word8 describing the
constructor (if the data type has more than one
constructor). For each type used in the constructor, we
call getSafePut (which immediately serializes the version
of the type). Then, for each field in the constructor, we
use one of the put functions obtained in the last step.

Note that by using getSafePut, we saved 4 bytes in the case
of the C constructor. For D and T0, we didn't save
anything. The instance derived by this function always use
at most the same space as those generated by
deriveSafeCopySimple, but never more (as we don't call
'getSafePut'/'getSafeGet' for types that aren't needed).

Derive an instance of SafeCopy. The instance derived by
this function should be compatible with the instance derived
by the module Happstack.Data.SerializeTH of the
happstack-data package. The instances use only safePut
and safeGet (as do the instances created by
deriveSafeCopySimple), but we also always write a Word8
tag, even if the data type isn't a sum type.

This instance always consumes at least the same space as
deriveSafeCopy or deriveSafeCopySimple, but may use more
because of the useless tag. So we recomend using it only if
you really need to read a previous version in this format,
and not for newer versions.