This creates a problem for some decoders that use peekTokenType and only look for the Type(U|N)Int(64) tokens and do not consider TypeInteger. Such decoders will not correctly round-trip via FlatTerm, where the will correctly round-trip via the binary CBOR representation.
The solution is to return TypeUInt64 and TypeNInt64 when the integer fits within the range, e.g.
tokenTypeOf (TkInteger n)
| n >= 0 && n < 2^64 = TypeUInt64
| n < 0 && n > -2^64 = TypeNInt64
| otherwise = TypeInteger
Alternatively, we could change the representation of FlatTerm to preserve more token type information, e.g. by splitting TkInt into TkUInt, TkNInt, TkUInt64, TkNInt64.
The implementation of
PeekTokenType
infromFlatTerm
only makes fairly coarse token type distinctions:https://github.com/well-typed/cborg/blob/41498491994c709091b82b799a76a71295b3186e/cborg/src/Codec/CBOR/FlatTerm.hs#L564-L567
In particular, it doesn't ever us
TypeUInt64
orTypeNInt64
:This creates a problem for some decoders that use
peekTokenType
and only look for theType(U|N)Int(64)
tokens and do not considerTypeInteger
. Such decoders will not correctly round-trip viaFlatTerm
, where the will correctly round-trip via the binary CBOR representation.The solution is to return
TypeUInt64
andTypeNInt64
when the integer fits within the range, e.g.Alternatively, we could change the representation of
FlatTerm
to preserve more token type information, e.g. by splittingTkInt
intoTkUInt
,TkNInt
,TkUInt64
,TkNInt64
.