| Copyright | Lennart Kolmodin | 
|---|---|
| License | BSD3-style (see LICENSE) | 
| Maintainer | Lennart Kolmodin <kolmodin@gmail.com> | 
| Stability | unstable | 
| Portability | portable to Hugs and GHC. Requires the FFI and some flexible instances. | 
| Safe Haskell | Trustworthy | 
| Language | Haskell98 | 
Data.Binary
Description
Binary serialisation of Haskell values to and from lazy ByteStrings.
 The Binary library provides methods for encoding Haskell values as
 streams of bytes directly in memory. The resulting ByteString can
 then be written to disk, sent over the network, or further processed
 (for example, compressed with gzip).
The binary package is notable in that it provides both pure, and
 high performance serialisation.
Values encoded using the Binary class are always encoded in network order
 (big endian) form, and encoded data should be portable across
 machine endianness, word size, or compiler version. For example,
 data encoded using the Binary class could be written on any machine,
 and read back on any another.
If the specifics of the data format is not important to you, for example,
 you are more interested in serializing and deserializing values than
 in which format will be used, it is possible to derive Binary
 instances using the generic support. See GBinaryGet and
 GBinaryPut.
If you have specific requirements about the encoding format, you can use the encoding and decoding primitives directly, see the modules Data.Binary.Get and Data.Binary.Put.
Synopsis
- class Binary t where
- class GBinaryGet f where
- class GBinaryPut f where
- data Get a
- type Put = PutM ()
- putWord8 :: Word8 -> Put
- getWord8 :: Get Word8
- encode :: Binary a => a -> ByteString
- decode :: Binary a => ByteString -> a
- decodeOrFail :: Binary a => ByteString -> Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
- encodeFile :: Binary a => FilePath -> a -> IO ()
- decodeFile :: Binary a => FilePath -> IO a
- decodeFileOrFail :: Binary a => FilePath -> IO (Either (ByteOffset, String) a)
- module Data.Word
The Binary class
The Binary class provides put and get, methods to encode and
 decode a Haskell value to a lazy ByteString. It mirrors the Read and
 Show classes for textual representation of Haskell types, and is
 suitable for serialising Haskell values to disk, over the network.
For decoding and generating simple external binary formats (e.g. C
 structures), Binary may be used, but in general is not suitable
 for complex protocols. Instead use the Put and Get primitives
 directly.
Instances of Binary should satisfy the following property:
decode . encode == id
That is, the get and put methods should be the inverse of each
 other. A range of instances are provided for basic Haskell types.
Minimal complete definition
Nothing
Methods
Encode a value in the Put monad.
Decode a value in the Get monad
Encode a list of values in the Put monad. The default implementation may be overridden to be more efficient but must still have the same encoding format.
Instances
| Binary All # | Since: binary-0.8.4.0 | 
| Binary Any # | Since: binary-0.8.4.0 | 
| Binary SomeTypeRep # | |
| Defined in Data.Binary.Class | |
| Binary Version # | Since: binary-0.8.0.0 | 
| Binary Void # | Since: binary-0.8.0.0 | 
| Binary Fingerprint # | Since: binary-0.7.6.0 | 
| Defined in Data.Binary.Class | |
| Binary Int16 # | |
| Binary Int32 # | |
| Binary Int64 # | |
| Binary Int8 # | |
| Binary Word16 # | |
| Binary Word32 # | |
| Binary Word64 # | |
| Binary ByteString # | |
| Defined in Data.Binary.Class | |
| Binary ByteString # | |
| Defined in Data.Binary.Class | |
| Binary ShortByteString # | |
| Defined in Data.Binary.Class Methods put :: ShortByteString -> Put # get :: Get ShortByteString # putList :: [ShortByteString] -> Put # | |
| Binary IntSet # | |
| Binary KindRep # | Since: binary-0.8.5.0 | 
| Binary Ordering # | |
| Binary TyCon # | Since: binary-0.8.5.0 | 
| Binary TypeLitSort # | Since: binary-0.8.5.0 | 
| Defined in Data.Binary.Class | |
| Binary Word8 # | |
| Binary Integer # | |
| Binary Natural # | Since: binary-0.7.3.0 | 
| Binary () # | |
| Binary Bool # | |
| Binary Char # | |
| Binary Double # | |
| Binary Float # | |
| Binary Int # | |
| Binary RuntimeRep # | Since: binary-0.8.5.0 | 
| Defined in Data.Binary.Class | |
| Binary VecCount # | Since: binary-0.8.5.0 | 
| Binary VecElem # | Since: binary-0.8.5.0 | 
| Binary Word # | |
| Binary a => Binary (Complex a) # | |
| Binary a => Binary (Identity a) # | |
| Binary a => Binary (First a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Last a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (First a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Last a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Max a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Min a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Option a) # | Since: binary-0.8.4.0 | 
| Binary m => Binary (WrappedMonoid m) # | Since: binary-0.8.4.0 | 
| Defined in Data.Binary.Class Methods put :: WrappedMonoid m -> Put # get :: Get (WrappedMonoid m) # putList :: [WrappedMonoid m] -> Put # | |
| Binary a => Binary (Dual a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Product a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (Sum a) # | Since: binary-0.8.4.0 | 
| Binary a => Binary (NonEmpty a) # | Since: binary-0.8.4.0 | 
| (Binary a, Integral a) => Binary (Ratio a) # | |
| Binary e => Binary (IntMap e) # | |
| Binary e => Binary (Seq e) # | |
| Binary a => Binary (Set a) # | |
| Binary e => Binary (Tree e) # | |
| Binary a => Binary (Maybe a) # | |
| Binary a => Binary [a] # | |
| (Binary i, Ix i, Binary e, IArray UArray e) => Binary (UArray i e) # | |
| (Binary a, Binary b) => Binary (Either a b) # | |
| Binary (Fixed a) # | Since: binary-0.8.0.0 | 
| (Binary a, Binary b) => Binary (Arg a b) # | Since: binary-0.8.4.0 | 
| Typeable a => Binary (TypeRep a) # | |
| (Binary i, Ix i, Binary e) => Binary (Array i e) # | |
| (Binary k, Binary e) => Binary (Map k e) # | |
| (Binary a, Binary b) => Binary (a, b) # | |
| Binary (f a) => Binary (Alt f a) # | Since: binary-0.8.4.0 | 
| (Binary a, Binary b, Binary c) => Binary (a, b, c) # | |
| (Binary a, Binary b, Binary c, Binary d) => Binary (a, b, c, d) # | |
| (Binary a, Binary b, Binary c, Binary d, Binary e) => Binary (a, b, c, d, e) # | |
| (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f) => Binary (a, b, c, d, e, f) # | |
| (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f, Binary g) => Binary (a, b, c, d, e, f, g) # | |
| (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f, Binary g, Binary h) => Binary (a, b, c, d, e, f, g, h) # | |
| (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f, Binary g, Binary h, Binary i) => Binary (a, b, c, d, e, f, g, h, i) # | |
| (Binary a, Binary b, Binary c, Binary d, Binary e, Binary f, Binary g, Binary h, Binary i, Binary j) => Binary (a, b, c, d, e, f, g, h, i, j) # | |
Example
To serialise a custom type, an instance of Binary for that type is required. For example, suppose we have a data structure:
data Exp = IntE Int
         | OpE  String Exp Exp
   deriving ShowWe can encode values of this type into bytestrings using the following instance, which proceeds by recursively breaking down the structure to serialise:
instance Binary Exp where
      put (IntE i)      = do put (0 :: Word8)
                             put i
      put (OpE s e1 e2) = do put (1 :: Word8)
                             put s
                             put e1
                             put e2
      get = do t <- get :: Get Word8
               case t of
                    0 -> do i <- get
                            return (IntE i)
                    1 -> do s  <- get
                            e1 <- get
                            e2 <- get
                            return (OpE s e1 e2)Note how we write an initial tag byte to indicate each variant of the data type.
We can simplify the writing of get instances using monadic
 combinators:
      get = do tag <- getWord8
               case tag of
                   0 -> liftM  IntE get
                   1 -> liftM3 OpE  get get getTo serialise this to a bytestring, we use encode, which packs the
 data structure into a binary format, in a lazy bytestring
> let e = OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2)) > let v = encode e
Where v is a binary encoded data structure. To reconstruct the
 original data, we use decode
> decode v :: Exp OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2))
The lazy ByteString that results from encode can be written to
 disk, and read from disk using Data.ByteString.Lazy IO functions,
 such as hPutStr or writeFile:
> writeFile "/tmp/exp.txt" (encode e)
And read back with:
> readFile "/tmp/exp.txt" >>= return . decode :: IO Exp OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2))
We can also directly serialise a value to and from a Handle, or a file:
> v <- decodeFile "/tmp/exp.txt" :: IO Exp OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2))
And write a value to disk
> encodeFile "/tmp/a.txt" v
Generic support
Beginning with GHC 7.2, it is possible to use binary serialization without writing any instance boilerplate code.
{-# LANGUAGE DeriveGeneric #-}
import Data.Binary
import GHC.Generics (Generic)
data Foo = Foo
         deriving (Generic)
-- GHC will automatically fill out the instance
instance Binary FooThis mechanism makes use of GHC's efficient built-in generics support.
class GBinaryGet f where #
Instances
| GBinaryGet (U1 :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| GBinaryGet (V1 :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| (GBinaryGet a, GBinaryGet b) => GBinaryGet (a :*: b :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| (GSumGet a, GSumGet b, SumSize a, SumSize b) => GBinaryGet (a :+: b :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| Binary a => GBinaryGet (K1 i a :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| GBinaryGet a => GBinaryGet (M1 i c a :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
class GBinaryPut f where #
Instances
| GBinaryPut (U1 :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| GBinaryPut (V1 :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| (GBinaryPut a, GBinaryPut b) => GBinaryPut (a :*: b :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| (GSumPut a, GSumPut b, SumSize a, SumSize b) => GBinaryPut (a :+: b :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| Binary a => GBinaryPut (K1 i a :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
| GBinaryPut a => GBinaryPut (M1 i c a :: Type -> Type) # | |
| Defined in Data.Binary.Generic | |
The Get and Put monads
Useful helpers for writing instances
Binary serialisation
encode :: Binary a => a -> ByteString #
Encode a value using binary serialisation to a lazy ByteString.
decode :: Binary a => ByteString -> a #
Decode a value from a lazy ByteString, reconstructing the original structure.
decodeOrFail :: Binary a => ByteString -> Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a) #
IO functions for serialisation
encodeFile :: Binary a => FilePath -> a -> IO () #
Lazily serialise a value to a file.
This is just a convenience function, it's defined simply as:
encodeFile f = B.writeFile f . encode
So for example if you wanted to compress as well, you could use:
B.writeFile f . compress . encode
decodeFile :: Binary a => FilePath -> IO a #
Decode a value from a file. In case of errors, error will
 be called with the error message.
Since: binary-0.7.0.0
decodeFileOrFail :: Binary a => FilePath -> IO (Either (ByteOffset, String) a) #
Decode a value from a file. In case of success, the value will be returned
 in Right. In case of decoder errors, the error message together with
 the byte offset will be returned.
module Data.Word