Safe Haskell | Safe-Inferred |
---|---|

Language | Haskell2010 |

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:

- Book-keeping details neccesary to write correct instances are hidden from the user.
- Inverse
`EncCBOR`

and`DecCBOR`

instances have visually similar definitions. - Advanced instances involving sparse-encoding, compact-representation, and
`Annotator`

instances are also supported.

A Guide to Visual inspection of Duality in Encode and Decode

`(Sum c)`

and`(SumD c)`

are duals`(Rec c)`

and`(RecD c)`

are duals`(Keyed c)`

and`(KeyedD c)`

are duals`(OmitC x)`

and`(Emit x)`

are duals`(Omit p ..)`

and`(Emit x)`

are duals if (p x) is True`(To x)`

and`(From)`

are duals if (x::T) and (forall (y::T). isRight (roundTrip y))`(E enc x)`

and`(D dec)`

are duals if (forall x . isRight (roundTrip' enc dec x))`(ED d x)`

and`(DD f)`

are duals as long as d=(Dual enc dec) and (forall x . isRight (roundTrip' enc dec x))`(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.

## Synopsis

- data Encode (w ∷ Wrapped) t where
- Rec ∷ t → Encode ('Closed 'Dense) t
- Sum ∷ t → Word → Encode 'Open t
- Keyed ∷ t → Encode ('Closed 'Sparse) t
- To ∷ EncCBOR a ⇒ a → Encode ('Closed 'Dense) a
- E ∷ (t → Encoding) → t → Encode ('Closed 'Dense) t
- MapE ∷ (a → b) → Encode w a → Encode w b
- OmitC ∷ t → Encode w t
- Tag ∷ Word → Encode ('Closed x) t → Encode ('Closed x) t
- Omit ∷ (t → Bool) → Encode ('Closed 'Sparse) t → Encode ('Closed 'Sparse) t
- Key ∷ Word → Encode ('Closed 'Dense) t → Encode ('Closed 'Sparse) t
- ApplyE ∷ Encode w (a → t) → Encode ('Closed r) a → Encode w t

- (!>) ∷ Encode w (a → t) → Encode ('Closed r) a → Encode w t
- encode ∷ Encode w t → Encoding
- runE ∷ Encode w t → t
- encodeDual ∷ ∀ t. (EncCBOR t, DecCBOR t) ⇒ t → Encode ('Closed 'Dense) t
- encodeKeyedStrictMaybeWith ∷ Word → (a → Encoding) → StrictMaybe a → Encode ('Closed 'Sparse) (StrictMaybe a)
- encodeKeyedStrictMaybe ∷ EncCBOR a ⇒ Word → StrictMaybe a → Encode ('Closed 'Sparse) (StrictMaybe a)

# 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

`(`

and *T* *b* *w*)`(`

and *T* $ *b* $ *w*)`(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 → Word → Encode '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). |

To ∷ EncCBOR 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). |

Tag ∷ Word → Encode ('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. |

Key ∷ Word → Encode ('Closed 'Dense) t → Encode ('Closed 'Sparse) t | Precede the encoding (in the produced bytes) with the key Word. Analagous to |

ApplyE ∷ Encode w (a → t) → Encode ('Closed r) a → Encode w t | Apply a functional encoding (arising from |

(!>) ∷ 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 `$`

encode ∷ Encode w t → Encoding Source #

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

.

# Index types for well-formed Coders.

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

encodeKeyedStrictMaybeWith ∷ Word → (a → Encoding) → StrictMaybe a → Encode ('Closed 'Sparse) (StrictMaybe a) Source #

encodeKeyedStrictMaybe ∷ EncCBOR a ⇒ Word → StrictMaybe a → Encode ('Closed 'Sparse) (StrictMaybe a) Source #