A restrained line drawing shows heterogeneous typed data traveling through encode and decode paths that close into a proved round trip, beside recursive JSON atom, array, and object constructors, four native scalar forms, and compact versus depth-indented rendering.
Lawful parameterized JSON codec

ff-json

repository URL pending

Scope

ff-json formalizes JSON as a recursive data type parameterized by an atom universe, allowing scalar representations to vary while arrays and objects retain a common structure. Its base layer covers atomic values, ordered array items, string-keyed object fields, string quoting, natural-number rendering, joining, and indentation. Both compact and depth-sensitive pretty rendering are included for the parameterized representation. A native instantiation supplies strings, natural numbers, Booleans, and null as the standard scalar cases. Typed conversion records, native constructors, and examples connect ordinary Agda values to JSON values and back.

Most important results

The parameterized Json type separates recursive JSON structure from the choice and rendering of atomic values. Compact and pretty renderers cover atoms, arrays, and objects, including quoted keys and nested indentation. The native layer provides JSON constructors and conversion instances for strings, natural numbers, Booleans, and JSON values themselves. A combined encoder-decoder interface records a round-trip proof that decoding an encoded value returns the original value, and the examples instantiate this interface for a user record.

Library modules

5 checked modules

Select a module to inspect its generated Agda source view.

Skip to content

Agda libraries

ff-json

Cubical Agda infrastructure for JSON-like values, rendering, and codec laws.

Lawful parameterized JSON codecA restrained line drawing shows heterogeneous typed data traveling through encode and decode paths that close into a proved round trip, beside recursive JSON atom, array, and object constructors, four native scalar forms, and compact versus depth-indented rendering.
A restrained line drawing shows heterogeneous typed data traveling through encode and decode paths that close into a proved round trip, beside recursive JSON atom, array, and object constructors, four native scalar forms, and compact versus depth-indented rendering.

Scope

ff-json formalizes JSON as a recursive data type parameterized by an atom universe, allowing scalar representations to vary while arrays and objects retain a common structure. Its base layer covers atomic values, ordered array items, string-keyed object fields, string quoting, natural-number rendering, joining, and indentation. Both compact and depth-sensitive pretty rendering are included for the parameterized representation. A native instantiation supplies strings, natural numbers, Booleans, and null as the standard scalar cases. Typed conversion records, native constructors, and examples connect ordinary Agda values to JSON values and back.

Most important results

The parameterized Json type separates recursive JSON structure from the choice and rendering of atomic values. Compact and pretty renderers cover atoms, arrays, and objects, including quoted keys and nested indentation. The native layer provides JSON constructors and conversion instances for strings, natural numbers, Booleans, and JSON values themselves. A combined encoder-decoder interface records a round-trip proof that decoding an encoded value returns the original value, and the examples instantiate this interface for a user record.

Used by

Source browser

Modules

Read the full library article

ff-json is a small Cubical Agda library for JSON-shaped data.

Its central design choice is that the recursive JSON tree is parameterized by an atom universe. That lets the same structure represent ordinary JSON and custom JSON-like data with domain-specific primitive atoms.

Public Core

The public entry point is FF.Json. It re-exports:

  • FF.Json.Base, with generic atom universes, generic JSON values, rendering, and codec records;
  • FF.Json.Native, with ordinary JSON atoms and native constructor helpers.

The generic atom universe has three parts:

Code: names for atom classes
El: the Agda type carried by each atom class
renderAtom: the renderer for that atom

The recursive JSON type has atoms, arrays, and objects. Object key order is preserved, and duplicate keys are representable; the library does not normalize or reject them.

Rendering And Codecs

The rendering surface includes compact and pretty rendering. The compact renderer emits no optional whitespace. The pretty renderer uses a two-space layout.

Codec records are explicit:

  • ToJSON' encodes a value into a Json U;
  • FromJSON' decodes a Json U into a Maybe A;
  • FromToJSON' packages both directions with a roundtrip law for encoded values.

That law is important. It does not say every JSON value decodes. It says values produced by the encoder decode back to the original Agda value.

Native JSON

The native universe includes strings, natural-number JSON numbers, booleans, and null. Full JSON numeric syntax is intentionally not modeled as one built-in numeric universe; negative numbers, fractions, and exponents can be represented by choosing a different atom universe.

Why It Matters

Proof-assistant workflows constantly cross boundaries. A browser edits a value. A server stores it. A code generator emits a module. A checker accepts or rejects generated source. JSON is a natural interchange format for those steps, but raw JSON strings do not say what has been preserved.

ff-json gives Formal Foundry a checked vocabulary for that boundary. The atom-universe design lets the same recursive tree support ordinary JSON and domain-specific JSON-like data. The codec records then make the important law explicit: values produced by an encoder decode back to the original Agda value.

That makes ff-json a foundation for other parts of the stack. ff-generics can serialize generic specifications and values. State-machine tooling can export structural machine data. MLTTDB-facing tools can use JSON-shaped values around generated records and editor contracts.

The public claim is simple: Formal Foundry does not treat data interchange as an untyped side channel. Even at the JSON layer, the system asks what shape is represented and which roundtrip properties hold.

Browse modulesOpen generated Agda sources

Cabinet index

Explore Formal Foundry

Search the archive

Find a page

Type to search the published content.