packman-0.3.0: Serialization library for GHC

Copyright(c) Jost Berthold, 2010-2015,
LicenseBSD3
MaintainerJost Berthold <jost.berthold@gmail.com>
Stabilityexperimental
Portabilityno (depends on GHC internals)
Safe HaskellNone
LanguageHaskell2010

GHC.Packing.Type

Description

Serialized type for the packman library, instances and helpers

The data type Serialized a includes a phantom type a to ensure type safety within one and the same program run. Type a can be polymorphic (at compile time, that is) when Serialized a is not used apart from being argument to deserialize.

The Show, Read, and Binary instances of Serialized a require an additional Typeable context (which requires a to be monomorphic) in order to implement dynamic type checks when parsing and deserialising data from external sources.

Synopsis

Documentation

data Serialized a Source

The type of Serialized data. Phantom type a ensures that we unpack data as the expected type.

Constructors

Serialized 

Instances

Typeable * a => Read (Serialized a)

Reads the format generated by the Show instance, checks hash values for executable and type and parses exactly as much as the included data size announces.

Typeable * a => Show (Serialized a)

prints packet as Word array in 4 columns (Word meaning the machine word size), and additionally includes Fingerprint hash values for executable binary and type.

Typeable * a => Binary (Serialized a)

The binary format of Serialized a data includes FingerPrint hash values for type and executable binary, which are checked when reading Serialized data back in using get.

The power of evaluation-orthogonal serialisation is that one can externalise partially evaluated data (containing thunks), for instance write it to disk or send it over a network. Therefore, the module defines a Binary instance for 'Serialized a', as well as instances for Read and Show@ which satisfy

read . show == id :: 'Serialized' a -> 'Serialized' a

The phantom type is enough to ensure type-correctness when serialised data remain in one single program run. However, when data from previous runs are read from an external source, their type needs to be checked at runtime. Type information must be stored together with the (binary) serialisation data.

The serialised data contain pointers to static data in the generating program (top-level functions and constants) and very likely to additional library code. Therefore, the exact same binary must be used when reading in serialised data from an external source. A hash of the executable is included in the representation to ensure this.

showWArray :: UArray Int TargetWord -> String Source

Helper to show a serialized structure as a packet (Word Array)

parseP :: ReadS (Int, FP, [TargetWord]) Source

Packet Parser, reads the format generated by the Read instance. Could also consume other formats of the array (not implemented). Returns: (data size in words, type fingerprint, array values)

 

data FP Source

The module uses a custom GHC fingerprint type with its two Word64 fields, to be able to read fingerprints

Constructors

FP Word64 Word64 

Instances

Eq FP 
Read FP 
Show FP 
Binary FP

Binary instance for fingerprint data (encoding TypeRep and executable in binary-encoded Serialized a)

matches :: Typeable a => a -> FP -> Bool Source

checks whether the type of the given expression matches the given Fingerprint

toFP :: Fingerprint -> FP Source

creates an FP from a GHC Fingerprint

typeFP :: Typeable a => a -> FP Source

returns the type fingerprint of an expression

prgHash :: FP Source

To check that the program (executable) is identical when packing and unpacking, the fingerprint type from above is used (Read/Show instances required). An FP fingerprint of the executable is computed once, by unsafePerformIO inside this CAF (safe to inline, just inefficient).

type TargetWord = Word64 Source

The target word size is the size of a machine word on the platform we run on.

This type is only used in Binary, Read and Show instances, where packets are stored as UArrays of TargetWord.

Actually, GHC uses machine word size (as Haskell 2010 spec. does not fix it) so we could just use Word. See http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/bugs-and-infelicities.html#haskell-98-2010-undefined