| Copyright | (c) 2026 The Polytropos Authors |
|---|---|
| License | EUPL-1.2 OR Apache-2.0 |
| Maintainer | nadia.yvette.chambers@ik.me |
| Stability | experimental |
| Portability | non-portable (GHC extensions) |
| Safe Haskell | None |
| Language | GHC2021 |
Polytropos.CBOR
Description
High-performance binary CBOR serialization of heterogeneous and homogeneous
polytropos open records and variants via cborg / serialise, without intermediate
tree boxing.
Architectural Overview & Rationale
Binary Wire Format
- A record encodes as a standard CBOR array: one length header (the row's arity) followed by the flat payload field encodings in row order.
- A variant encodes as a CBOR array consisting of the constructor's
Wordtag followed by that constructor's payload field encodings.
Positional & Allocation-Free
Because field names exist only at the type level in row polymorphism, the binary
encoder is purely positional: no string keys are written to the wire. Encoding
and decoding are executed as single unrolled passes directly over the flat
Rep payload array with no intermediate allocations.
Truly Heterogeneous Row Support
Unlike satellites restricted to homogeneous types, polytropos-cbor provides genuine
heterogeneous serialization across open rows via AllSerialise: every field requires
Serialise at its own concrete type, so rows mixing String, Int, Word, custom
types, or nested rows serialize and deserialize directly.
When to Use This Module
- When network bandwidth, binary storage size, and serialization speed are critical.
- For inter-service RPC, binary logs, and compact caching.
Worked Example
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fplugin=Polytropos.Plugin #-}
import Codec.Serialise (serialise, deserialise)
import Polytropos
import Polytropos.CBOR
-- A genuinely heterogeneous record:
type Packet = Record '["id" ':= Int, "payload" ':= String, "flags" ':= Word]
pkt :: Packet
pkt = REC { id = 101, payload = "sensor-ok", flags = 0 }
-- Serializes to compact positional CBOR binary:
bytes = serialise pkt
-- Deserializes back to Packet:
pkt' :: Packet
pkt' = deserialise bytesSynopsis
- class AllSerialise (r :: Row) where
- encRecordCBOR :: Proxy r -> [Identity (Any :: Type)] -> Encoding
- decRecordCBOR :: Proxy r -> Decoder s [Identity (Any :: Type)]
- class FieldCount (r :: Row) where
- fieldCount :: Proxy r -> Int
- class AllCtorsSerialise (s :: SumRow) where
- encVariantCBOR :: Proxy s -> Word -> Word -> [Identity (Any :: Type)] -> Encoding
- decVariantCBOR :: Proxy s -> Word -> Int -> Decoder t [Identity (Any :: Type)]
- type family AllFieldsAre a (r :: Row) where ...
- class AllCtorsHom a (s :: SumRow) where
- ctorArities :: Proxy a -> Proxy s -> [(String, Int)]
- type family RowField (r :: Row) where ...
- type family SumField (s :: SumRow) where ...
Heterogeneous Row Codecs
class AllSerialise (r :: Row) where Source #
Evidence that every field of the row r has a Serialise instance
at that field's own type. Serializes the erased payload slots in row order.
Methods
encRecordCBOR :: Proxy r -> [Identity (Any :: Type)] -> Encoding Source #
decRecordCBOR :: Proxy r -> Decoder s [Identity (Any :: Type)] Source #
Instances
| AllSerialise ('[] :: [Pair Symbol Type]) Source # | |
Defined in Polytropos.CBOR Methods encRecordCBOR :: Proxy ('[] :: [Pair Symbol Type]) -> [Identity (Any :: Type)] -> Encoding Source # decRecordCBOR :: Proxy ('[] :: [Pair Symbol Type]) -> Decoder s [Identity (Any :: Type)] Source # | |
| (Serialise a, AllSerialise r) => AllSerialise ((n ':= a) ': r) Source # | |
Defined in Polytropos.CBOR Methods encRecordCBOR :: Proxy ((n ':= a) ': r) -> [Identity (Any :: Type)] -> Encoding Source # decRecordCBOR :: Proxy ((n ':= a) ': r) -> Decoder s [Identity (Any :: Type)] Source # | |
class FieldCount (r :: Row) where Source #
Computes the arity (field count) of a row at compile time.
Methods
fieldCount :: Proxy r -> Int Source #
Instances
| FieldCount ('[] :: [Pair Symbol Type]) Source # | |
Defined in Polytropos.CBOR Methods fieldCount :: Proxy ('[] :: [Pair Symbol Type]) -> Int Source # | |
| FieldCount r => FieldCount ((n ':= a) ': r) Source # | |
Defined in Polytropos.CBOR Methods fieldCount :: Proxy ((n ':= a) ': r) -> Int Source # | |
class AllCtorsSerialise (s :: SumRow) where Source #
Evidence that every constructor of the sum row s has a heterogeneous
field row satisfying AllSerialise, paired with its constructor tag index.
Methods
encVariantCBOR :: Proxy s -> Word -> Word -> [Identity (Any :: Type)] -> Encoding Source #
decVariantCBOR :: Proxy s -> Word -> Int -> Decoder t [Identity (Any :: Type)] Source #
Instances
| AllCtorsSerialise ('[] :: [Pair Symbol Row]) Source # | |
Defined in Polytropos.CBOR | |
| (FieldCount fs, AllSerialise fs, AllCtorsSerialise s) => AllCtorsSerialise ((c ':= fs) ': s) Source # | |
Defined in Polytropos.CBOR Methods encVariantCBOR :: Proxy ((c ':= fs) ': s) -> Word -> Word -> [Identity (Any :: Type)] -> Encoding Source # decVariantCBOR :: Proxy ((c ':= fs) ': s) -> Word -> Int -> Decoder t [Identity (Any :: Type)] Source # | |
Homogeneity Evidence and Introspection Helpers
Homogeneity Evidence and Introspection Helpers
In addition to the primary heterogeneous codecs (AllSerialise, AllCtorsSerialise),
this module provides closed type families and reflection classes for
inspecting row metadata and enforcing uniform payload types.
type family AllFieldsAre a (r :: Row) where ... Source #
Evidence that every field of the row r has type a.
Equations
| AllFieldsAre _1 ('[] :: [Pair Symbol Type]) = () | |
| AllFieldsAre a ((n ':= a) ': rest) = AllFieldsAre a rest |
class AllCtorsHom a (s :: SumRow) where Source #
Every constructor of the sum row s has a homogeneous field row of type
a, reified as constructor names paired with their arities.
Methods
ctorArities :: Proxy a -> Proxy s -> [(String, Int)] Source #
Instances
| AllCtorsHom a ('[] :: [Pair Symbol Row]) Source # | |
Defined in Polytropos.CBOR Methods ctorArities :: Proxy a -> Proxy ('[] :: [Pair Symbol Row]) -> [(String, Int)] Source # | |
| (KnownSymbol c, AllFieldsAre a fs, AllCtorsHom a s) => AllCtorsHom a ((c ':= fs) ': s) Source # | |
Defined in Polytropos.CBOR Methods ctorArities :: Proxy a -> Proxy ((c ':= fs) ': s) -> [(String, Int)] Source # | |
type family RowField (r :: Row) where ... Source #
The field type of a homogeneous row: the type of every field, Void
for the empty row.
type family SumField (s :: SumRow) where ... Source #
The field type shared by every constructor of a sum row, Void for the
empty sum.
Orphan instances
| (FieldCount r, AllSerialise r) => Serialise (Record r) Source # | |
| AllCtorsSerialise s => Serialise (Variant s) Source # | |