-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Type-safe binary serialization
--
-- Binary serialization tagged with type information, allowing for
-- typechecking and useful error messages at the receiving site.
--
-- This package serves the same purpose as tagged-binary, with a couple
-- of key differences:
--
--
-- - Support of different kinds of serialized type annotations, each
-- with specific strengths and weaknesses.
-- - Error messages can provide details on type errors at the cost of
-- longer message lengths to include the necessary information.
-- - Serialization computationally almost as efficient as
-- Data.Binary when precaching type representations; decoding
-- however is slower. These values obviously depend a lot on the involved
-- data and its type; an example benchmark is shown in the picture
-- below.
-- - No depencency on Internal modules of other libraries, and
-- a very small dependency footprint in general.
--
--
-- For information about usage, see the Data.Binary.Typed.Tutorial
-- module.
--
-- Performance-wise, here is a value Right (Left <100 chars
-- lipsum>) of type Either (Char, Int) (Either String (Maybe
-- Integer)) benchmarked using the Hashed64 type
-- representation:
--
--
-- (local copy)
@package binary-typed
@version 0.2.0.0
-- | Internals, exposed mostly for potential use by testsuites and
-- benchmarks.
--
-- __Not recommended to be used from within other independent
-- libraries.__
module Data.Binary.Typed.Internal
-- | A value suitable to be typechecked using the contained extra type
-- information.
data Typed a
-- | Using this data constructor directly is unsafe, as it allows
-- construction of ill-typed Typed data. Use the typed
-- smart constructor unless you really need Typed.
Typed :: TypeInformation -> a -> Typed a
-- | Type information stored alongside a value to be serialized, so that
-- the recipient can do consistency checks. See TypeFormat for
-- more detailed information on the fields.
data TypeInformation
Untyped' :: TypeInformation
Hashed32' :: Hash32 -> TypeInformation
Hashed64' :: Hash64 -> TypeInformation
Shown' :: Hash32 -> String -> TypeInformation
Full' :: TypeRep -> TypeInformation
Cached' :: ByteString -> TypeInformation
-- | A hash value of a TypeRep. Currently a 32-bit value created
-- using the MurmurHash2 algorithm.
newtype Hash32
Hash32 :: Word32 -> Hash32
-- | A hash value of a TypeRep. Currently a 64-bit value created
-- using the MurmurHash2 algorithm.
newtype Hash64
Hash64 :: Word64 -> Hash64
-- | Construct a Typed value using the chosen type format.
--
-- Example:
--
--
-- value = typed Full (hello, 1 :: Int, 2.34 :: Double)
-- encded = encode value
--
--
-- The decode site can now verify whether decoding happens with the right
-- type.
typed :: Typeable a => TypeFormat -> a -> Typed a
-- | Create the TypeInformation to be stored inside a Typed
-- value from a TypeRep.
makeTypeInformation :: TypeFormat -> TypeRep -> TypeInformation
-- | Different ways of including/verifying type information of serialized
-- messages.
data TypeFormat
-- | Include no type information.
--
--
-- - Requires one byte more compared to using Binary directly
-- (to tag the data as untyped, required for the decoding step).
--
Untyped :: TypeFormat
-- | Compare types by their hash values (using the MurmurHash2 algorithm).
--
--
-- - Requires five bytes more compared to using Binary directly
-- for the type information (one to tag as Hashed32, four for the
-- hash value) * Subject to false positive due to hash collisions,
-- although in practice this should almost never happen. * Type errors
-- cannot tell the provided type (Expected X, received type with hash
-- H)
--
Hashed32 :: TypeFormat
-- | Like Hashed32, but uses a 64-bit hash value.
--
--
-- - Requires nine bytes more compared to using Binary. * Hash
-- collisions are even less likely to occur than with
-- Hashed32.
--
Hashed64 :: TypeFormat
-- | Compare String representation of types, obtained by calling
-- show on the TypeRep, and also include a hash value (like
-- Hashed32). The former is mostly for readable error messages,
-- the latter provides better collision resistance.
--
--
-- - Data size larger than Hashed32, but usually smaller than
-- Full. * Both the hash and the shown type must match to satisfy
-- the typechecker. * Useful type errors (expected X, received Y).
-- All types are shown unqualified though, making Foo.X and
-- Bar.X look identical in error messages. Remember this when
-- you get a seemingly silly error expected Foo, but given
-- Foo.
--
Shown :: TypeFormat
-- | Compare the full representation of a data type.
--
--
-- - More verbose than Hashed and Shown. As a rule of
-- thumb, transmitted data is roughly the same as Shown, but all
-- names are fully qualified (package, module, type name). * Correct
-- comparison (no false positives). An semi-exception here is when types
-- change between package versions: package-1.0 Foo.X and
-- package-1.1 Foo.X count as the same type. * Useful type
-- errors (expected X, received Y). All types are shown
-- unqualified though, making Foo.X and Bar.X look
-- identical in error messages. Remember this when you get a seemingly
-- silly error expected Foo, but given Foo.
--
Full :: TypeFormat
-- | Extract which TypeFormat was used to create a certain
-- TypeInformation.
--
-- If the type is Cached', then the contained information is
-- assumed well-formed. In the public API, this is safe to do, since only
-- well-typed Typed values can be created in the first place.
getFormat :: TypeInformation -> TypeFormat
-- | Typecheck a Typed. Returns the (well-typed) input, or an error
-- message if the types don't work out.
typecheck :: Typeable a => Typed a -> Either String (Typed a)
-- | Extract the value of a Typed, i.e. strip off the explicit type
-- information.
--
-- This function is safe to use for all Typed values created by
-- the public API, since all construction sites ensure the actual type
-- matches the contained type description.
--
--
-- erase (typed format x) == x
--
erase :: Typed a -> a
-- | Sometimes it can be beneficial to serialize the type information in
-- advance, so that the maybe costly serialization step does not have to
-- be repeated on every invocation of encode. Preserialization
-- comes at a price though, as the directly contained
-- ByteStringrequires its length to be included in the final
-- serialization, yielding a 8-byte overhead for the required
-- Int64, and one for the tag of what was serialized (shown or
-- full?).
--
-- This function calculates the serialized version of
-- TypeInformation in cases where the required 8 bytes are
-- negligible (determined by an arbitrary threshold, currently 10*9
-- bytes).
--
-- Used to make encodeTyped more efficient; the source there also
-- makes a good usage example.
preserialize :: TypeInformation -> TypeInformation
-- | TypeRep without the (internal) fingerprint.
data TypeRep
TypeRep :: TyCon -> [TypeRep] -> TypeRep
-- | Strip a TypeRep off the fingerprint. Inverse of
-- unStripTypeRep.
stripTypeRep :: TypeRep -> TypeRep
-- | Add a fingerprint to a TypeRep. Inverse of stripTypeRep.
unStripTypeRep :: TypeRep -> TypeRep
-- | Hash a TypeRep to a 32-bit digest.
hashType32 :: TypeRep -> Hash32
-- | Hash a TypeRep to a 64-bit digest.
hashType64 :: TypeRep -> Hash64
-- | TyCon without the (internal) fingerprint.
data TyCon
-- | Package, module, constructor name
TyCon :: String -> String -> String -> TyCon
-- | Strip a TyCon off the fingerprint. Inverse of
-- unStripTyCon.
stripTyCon :: TyCon -> TyCon
-- | Add a fingerprint to a TyCon. Inverse of stripTyCon.
unStripTyCon :: TyCon -> TyCon
instance Eq Hash32
instance Ord Hash32
instance Show Hash32
instance Generic Hash32
instance Eq Hash64
instance Ord Hash64
instance Show Hash64
instance Generic Hash64
instance Eq TypeFormat
instance Ord TypeFormat
instance Show TypeFormat
instance Eq TyCon
instance Ord TyCon
instance Generic TyCon
instance Eq TypeRep
instance Ord TypeRep
instance Generic TypeRep
instance Eq TypeInformation
instance Ord TypeInformation
instance Show TypeInformation
instance Generic TypeInformation
instance Datatype D1Hash32
instance Constructor C1_0Hash32
instance Datatype D1Hash64
instance Constructor C1_0Hash64
instance Datatype D1TyCon
instance Constructor C1_0TyCon
instance Datatype D1TypeRep
instance Constructor C1_0TypeRep
instance Datatype D1TypeInformation
instance Constructor C1_0TypeInformation
instance Constructor C1_1TypeInformation
instance Constructor C1_2TypeInformation
instance Constructor C1_3TypeInformation
instance Constructor C1_4TypeInformation
instance Constructor C1_5TypeInformation
instance Hashable64 TyCon
instance Hashable32 TyCon
instance Show TyCon
instance Binary TyCon
instance Hashable64 TypeRep
instance Hashable32 TypeRep
instance Show TypeRep
instance Binary TypeRep
instance (Binary a, Typeable a) => Binary (Typed a)
instance Show a => Show (Typed a)
instance Binary Hash64
instance Binary Hash32
instance Binary TypeInformation
-- | Defines a type-safe Binary instance to ensure data is decoded
-- with the type it was serialized from.
--
-- For usage information, see the Data.Binary.Typed.Tutorial
-- module.
module Data.Binary.Typed
-- | A value suitable to be typechecked using the contained extra type
-- information.
data Typed a
-- | Construct a Typed value using the chosen type format.
--
-- Example:
--
--
-- value = typed Full (hello, 1 :: Int, 2.34 :: Double)
-- encded = encode value
--
--
-- The decode site can now verify whether decoding happens with the right
-- type.
typed :: Typeable a => TypeFormat -> a -> Typed a
-- | Different ways of including/verifying type information of serialized
-- messages.
data TypeFormat
-- | Include no type information.
--
--
-- - Requires one byte more compared to using Binary directly
-- (to tag the data as untyped, required for the decoding step).
--
Untyped :: TypeFormat
-- | Compare types by their hash values (using the MurmurHash2 algorithm).
--
--
-- - Requires five bytes more compared to using Binary directly
-- for the type information (one to tag as Hashed32, four for the
-- hash value) * Subject to false positive due to hash collisions,
-- although in practice this should almost never happen. * Type errors
-- cannot tell the provided type (Expected X, received type with hash
-- H)
--
Hashed32 :: TypeFormat
-- | Like Hashed32, but uses a 64-bit hash value.
--
--
-- - Requires nine bytes more compared to using Binary. * Hash
-- collisions are even less likely to occur than with
-- Hashed32.
--
Hashed64 :: TypeFormat
-- | Compare String representation of types, obtained by calling
-- show on the TypeRep, and also include a hash value (like
-- Hashed32). The former is mostly for readable error messages,
-- the latter provides better collision resistance.
--
--
-- - Data size larger than Hashed32, but usually smaller than
-- Full. * Both the hash and the shown type must match to satisfy
-- the typechecker. * Useful type errors (expected X, received Y).
-- All types are shown unqualified though, making Foo.X and
-- Bar.X look identical in error messages. Remember this when
-- you get a seemingly silly error expected Foo, but given
-- Foo.
--
Shown :: TypeFormat
-- | Compare the full representation of a data type.
--
--
-- - More verbose than Hashed and Shown. As a rule of
-- thumb, transmitted data is roughly the same as Shown, but all
-- names are fully qualified (package, module, type name). * Correct
-- comparison (no false positives). An semi-exception here is when types
-- change between package versions: package-1.0 Foo.X and
-- package-1.1 Foo.X count as the same type. * Useful type
-- errors (expected X, received Y). All types are shown
-- unqualified though, making Foo.X and Bar.X look
-- identical in error messages. Remember this when you get a seemingly
-- silly error expected Foo, but given Foo.
--
Full :: TypeFormat
-- | Extract the value of a Typed, i.e. strip off the explicit type
-- information.
--
-- This function is safe to use for all Typed values created by
-- the public API, since all construction sites ensure the actual type
-- matches the contained type description.
--
--
-- erase (typed format x) == x
--
erase :: Typed a -> a
-- | Modify the value contained in a Typed, keeping the same sort of
-- type representation. In other words, calling mapTyped on
-- something that is typed using Hashed will yield a
-- Hashed value again.
--
-- Note: this destroys precached information, so that values
-- have to be precached again if desired. As a consequence,
-- mapTyped id can be used to un-precache
-- values.
mapTyped :: Typeable b => (a -> b) -> Typed a -> Typed b
-- | Change the value contained in a Typed, leaving the type
-- representation unchanged. This can be useful to avoid recomputation of
-- the included type information, and can improve performance
-- significantly if many individual messages are serialized.
--
-- Can be seen as a more efficient mapTyped in case f is
-- an endomorphism (i.e. has type a -> a).
reValue :: (a -> a) -> Typed a -> Typed a
-- | Change the way a type is represented inside a Typed value.
--
--
-- reType format x = typed format (erase x)
--
reType :: Typeable a => TypeFormat -> Typed a -> Typed a
-- | Sometimes it can be beneficial to serialize the type information in
-- advance, so that the maybe costly serialization step does not have to
-- be repeated on every invocation of encode. Preserialization
-- comes at a price though, as the directly contained
-- ByteStringrequires its length to be included in the final
-- serialization, yielding a 8-byte overhead for the required
-- Int64, and one for the tag of what was serialized (shown or
-- full?).
--
-- This function calculates the serialized version of
-- TypeInformation in cases where the required 8 bytes are
-- negligible (determined by an arbitrary threshold, currently 10*9
-- bytes).
--
-- Used to make encodeTyped more efficient; the source there also
-- makes a good usage example.
preserialize :: TypeInformation -> TypeInformation
-- | Encode a Typeable value to ByteString that includes type
-- information. This function is useful to create specialized typed
-- encoding functions, because the type information is cached and does
-- not need to be recalculated on every serialization.
--
-- Observationally, encodeTyped format value is
-- equivalent to encode (typed format value).
-- However, encodeTyped does the type information related
-- calculations in advance and shares the results between future
-- invocations of it, making it much more efficient to serialize many
-- values of the same type.
encodeTyped :: (Typeable a, Binary a) => TypeFormat -> a -> ByteString
-- | Deprecated: encodeTyped now caches automatically for all
-- types
encodeTypedLike :: (Typeable a, Binary a) => Typed a -> a -> ByteString
decodeTyped :: (Typeable a, Binary a) => ByteString -> Either String a
-- | Safely decode data, yielding Either an error String or
-- the value, along with meta-information of the consumed binary data.
--
--
decodeTypedOrFail :: (Typeable a, Binary a) => ByteString -> Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
unsafeDecodeTyped :: (Typeable a, Binary a) => ByteString -> a
-- | This meta-module exists only for documentational purposes; the library
-- functionality is found in Data.Binary.Typed.
module Data.Binary.Typed.Tutorial