Reified.Schema
PackageSchema
The Schema module contains primitive schemas, collection and recursion combinators, union constructors, and the
operations that parse or check a completed declaration.
Start from the task:
- Declare a record schema and parse untrusted input: Schema quickstart.
- Fields, field blocks, and constructors: SchemaDSL.
- Reusable value rules: Constraints.
- Invariant-carrying field types: Refined Schemas.
- JSON in and out: JSON Codecs.
- Published shape:
JsonSchema. - Older wire versions: Versioned Contracts.
Use Schema.parse for untrusted Data. It decodes fields, applies constraints and refinements, accumulates independent
failures as SchemaErrors, and invokes the model constructor only after the fields succeed.
Use Schema.check when a typed value came from another constructor, an import, or a database mapper. It reads the
declared fields back from the value and checks them.
The same model constructor runs again, so cross-field invariants are checked too. Success returns the checked value itself.
Both operations return Result<_, SchemaErrors>. The difference is only the input: Schema.parse reads untrusted
Data and decodes each field, while Schema.check reads fields back from a value that already exists. The field
rules, constructor, error cases, and paths are the same.
open Reified.SchemaDSL
open Reified.ConstraintDSL
type Signup = { Email: string; Age: int }
let signupSchema =
schema<Signup> {
field _.Email { constraints [ present; email ] }
field _.Age { constrain (atLeast 13) }
construct (fun email age -> { Email = email; Age = age })
}
let input = Data.ofNameValues [ "email", "ada"; "age", "11" ]
Schema.parse signupSchema input
// Result<Signup, SchemaErrors>: untrusted Data, every field checked and accumulated
Schema.check signupSchema { Email = "ada"; Age = 11 }
// Result<Signup, SchemaErrors>: an existing value, the same field rules and constructor
The Schema quickstart introduces the workflow.
Constraint equivalents
These are the handwritten operations emitted for derivation attributes. Use them inside a field block with
constrain, except for the metadata operations shown directly:
| Purpose | Schema DSL |
|---|---|
| Pattern | constrain (pattern expression) |
| Minimum, maximum, exact, or bounded natural length | constrain (minLength n), maxLength, length, lengthBetween |
| Present value or supplied input key | constrain present, mustSupply |
| Inclusive/exclusive numeric bounds | constrain (atLeast n), greaterThan, atMost, lessThan |
| Numeric multiple | constrain (multipleOf n) |
| Distinct list elements | constrain distinct |
| Email text | constrain email |
| Open format metadata | format (SchemaFormat.create name) |
| Omitted-input default | defaultValue value |
See Derivation Attributes for the complete attribute mapping.