packman-0.5.0: Serialization library for GHC

Copyright(c) Jost Berthold 2010-2015
MaintainerJost Berthold <>
Portabilityno (depends on GHC internals)
Safe HaskellNone



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.



data Serialized a Source #

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




Typeable * a => Read (Serialized a) Source #

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) Source #

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) Source #

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.


put :: Serialized a -> Put #

get :: Get (Serialized a) #

putList :: [Serialized a] -> Put #

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


FP Word64 Word64 


Eq FP Source # 


(==) :: FP -> FP -> Bool #

(/=) :: FP -> FP -> Bool #

Read FP Source # 
Show FP Source # 


showsPrec :: Int -> FP -> ShowS #

show :: FP -> String #

showList :: [FP] -> ShowS #

Binary FP Source #

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


put :: FP -> Put #

get :: Get FP #

putList :: [FP] -> Put #

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