cardano-ledger-binary- Binary serialization library used throughout ledger
Safe HaskellSafe-Inferred



Data.Coders provides tools for writing EncCBOR and DecCBOR instances (see module Binary) in an intuitive way that mirrors the way one constructs values of a particular type. Advantages include:

  1. Book-keeping details neccesary to write correct instances are hidden from the user.
  2. Inverse EncCBOR and DecCBOR instances have visually similar definitions.
  3. Advanced instances involving sparse-encoding, compact-representation, and Annotator instances are also supported.

A Guide to Visual inspection of Duality in Encode and Decode

  1. (Sum c) and (SumD c) are duals
  2. (Rec c) and (RecD c) are duals
  3. (Keyed c) and (KeyedD c) are duals
  4. (OmitC x) and (Emit x) are duals
  5. (Omit p ..) and (Emit x) are duals if (p x) is True
  6. (To x) and (From) are duals if (x::T) and (forall (y::T). isRight (roundTrip y))
  7. (E enc x) and (D dec) are duals if (forall x . isRight (roundTrip' enc dec x))
  8. (ED d x) and (DD f) are duals as long as d=(Dual enc dec) and (forall x . isRight (roundTrip' enc dec x))
  9. (f !> x) and (g <! y) are duals if (f and g are duals) and (x and y are duals)

Duality properties of (Summands name decodeT) and (SparseKeyed name (init::T) pick required) also exist but are harder to describe succinctly.


Creating encoders.

data Encode (w ∷ Wrapped) t where Source #

A first-order domain specific langage for describing EncCBOR instances. Applying the interpreter encode to a well-typed (Encode w T) always produces a valid encoding for T. Constructing an Encode of type T is just like building a value of type T, applying a constructor of T to the correctly typed arguments. For example

data T = T Bool Word

instance EncCBOR T where
  encCBOR (T b w) = encode (Rec T !> To b !> To w)

Note the similarity of

(T b w) and (T $ b $ w) and (Rec T !> To b !> To w)

Where (!>) is the infx version of ApplyE with the same infixity and precedence as ($). Note how the constructor and each (component, field, argument) is labeled with one of the constructors of Encode, and are combined with the application operator (!>). Using different constructors supports different styles of encoding.


Rec ∷ t → Encode ('Closed 'Dense) t

Label the constructor of a Record-like datatype (one with exactly 1 constructor) as an Encode.

Sum ∷ t → WordEncode 'Open t

Label one of the constructors of a sum datatype (one with multiple constructors) as an Encode

Keyed ∷ t → Encode ('Closed 'Sparse) t

Label the constructor of a Record-like datatype as being encoded sparsely (storing only non-default values).

ToEncCBOR a ⇒ a → Encode ('Closed 'Dense) a

Label an (component, field, argument) to be encoded using an existing EncCBOR instance.

E ∷ (t → Encoding) → t → Encode ('Closed 'Dense) t

Label an (component, field, argument) to be encoded using an existing EncCBOR instance.

MapE ∷ (a → b) → Encode w a → Encode w b

Lift one Encode to another with a different type. Used to make a Functor instance of (Encode w).

OmitC ∷ t → Encode w t

Skip over the (component,field, argument), don't encode it at all (used in sparse encoding).

TagWordEncode ('Closed x) t → Encode ('Closed x) t

Precede the given encoding (in the produced bytes) with the given tag Word.

Omit ∷ (t → Bool) → Encode ('Closed 'Sparse) t → Encode ('Closed 'Sparse) t

Omit the (component,field, argument) if the function is True, otherwise encode with the given encoding.

KeyWordEncode ('Closed 'Dense) t → Encode ('Closed 'Sparse) t

Precede the encoding (in the produced bytes) with the key Word. Analagous to Tag, but lifts a Dense encoding to a Sparse encoding.

ApplyEEncode w (a → t) → Encode ('Closed r) a → Encode w t

Apply a functional encoding (arising from Rec or Sum) to get (type wise) smaller encoding. A fully saturated chain of ApplyE will be a complete encoding. See also !> which is infix ApplyE.

(!>)Encode w (a → t) → Encode ('Closed r) a → Encode w t infixl 4 Source #

Infix operator version of ApplyE. Has the same infxity and operator precedence as $

encodeEncode w t → Encoding Source #

Translate a first-order @(Encode w d) domain specific langage program, into an Encoding .

Index types for well-formed Coders.

runEEncode w t → t Source #

encodeDual ∷ ∀ t. (EncCBOR t, DecCBOR t) ⇒ t → Encode ('Closed 'Dense) t Source #

Use encodeDual and decodeDual, when you want to guarantee that a type has both EncCBOR and FromCBR instances.

Containers, Combinators, Annotators