Unions: or and never

Status: implemented

or(a, b, …) admits every value any of its members admits. never is the empty union, or(), and admits nothing.

const shape = or(
    { kind: 'circle', r: number },
    { kind: 'square', side: number },
)
const id = or(string, number)

or is a lazy constructor: it captures its members in a thunk and does no flattening, deduplication or subset analysis. That algebra is the data form's: toData merges members kind by kind, absorbs a constant into its whole kind (or(42, number) is all numbers), drops a member another covers, and orders what is left canonically. So two spellings of one set have one data form, and equal says so: or(true, false) and boolean are equal, and subset(toData(42))(toData(number)) holds.

never is what an empty rest is: rest(c, never) is the closed c (open containers). A union with option is how a member is made optional.

Examples

The demo on this page runs the Two spellings, one set lesson: pick or(true, false) or boolean, and the comparison under the graph reports equal → true; the TypeScript type and the JSON Schema of the two are the same. The lesson is defined in sample.f.mjs, and the module page's demo lists it among all the others.

Reference

Where it is implemented

or and never in module.f.mjs; normalization, equal, cmp and subset in data, which documents them (data/README.md).

Demo

or(true, false) and boolean are written differently and accept exactly the same values.

ortruefalse

TypeScript:

boolean

JSON Schema:

{"type":"boolean"}
Canonical form (toData)
export default [{},{"unit":12}];

One set: the two schemas have one canonical form.

equal → true
subset(this)(that) → true
subset(that)(this) → true

parse · ok

export default true;

validate · ok

export default true;

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs