Repository F# setup
open Reified
open Reified.Refinements
open Reified.Result
open Reified.Schema.Json

Quickstart

Install the constraint package:

dotnet add package Reified.Constraint
open Reified

let name : Constraint<string> =
    Constraint.all [ Constraint.present; Constraint.maxLength 80 ]

Constraint.check confirms whether a typed value is acceptable:

Constraint.check name "Ada"
// Ok ()

Constraint.check name ""
// Error [ Blank ]

Use Constraint.guard when the successful result should retain the unchanged input:

let checkedName : Result<string, Violation> =
    Constraint.guard name "Ada"

Constraints never parse or normalize values. Parsing changes serialized text into a typed value. Refined records successful admission in a destination type.

Keep each Violation structured inside application errors. Render it only at the UI, log, or other presentation edge:

Constraint.check name ""
|> Result.mapError Violation.render
// Error "value must be present"

Continue with Constraint for the core model, Reusable constraints for interpreted and opaque rules, and Working with violations for inspection and rendering.