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

Result handling

Reified.Result works with the standard F# Result<'value, 'error> - ordinary Ok or Error values that any other F# code can pattern match.

What it provides is a module and DSL for working with them - turning ordinary values into a Result, chaining steps, replacing one error with another, getting values back out, and two computation expressions for writing sequences of fallible steps as straight-line code.

dotnet add package Reified.Result

A first example

open System
open Reified.Result
open Reified.ResultDSL

type SignupError =
    | NameMissing
    | AgeNotANumber of string
    | AgeOutOfRange of int

let parseName raw =
    raw
    |> Result.failIf String.IsNullOrWhiteSpace
    |> Result.orError NameMissing

let parseAge raw =
    Int32.TryParse raw
    |> Result.fromTry
    |> Result.orError (AgeNotANumber raw)
    |> Result.bind (fun age ->
        if age >= 0 && age < 130 then Ok age else Error (AgeOutOfRange age))

result {
    let! name = parseName "Ada"
    let! age = parseAge "36"
    return {| Name = name; Age = age |}
}
Ok { Name = "Ada"; Age = 36 }

Every page below builds on this same parseName/parseAge pair, so the examples compose with each other.

Pages

Reified.Result composes failures. Admitting values in the first place is the Constraints test typed values, Parsing decodes serialized primitives, and Refined constructs values whose types record a successful check. All three return the standard F# Result, so these helpers work on their output — but none requires this package, and this package does not require them.

Accumulation here is flat: result.list { } collects a list of your error values with no field identity. When a whole form, request, or document must become a model with path-aware accumulated diagnostics, that is Reified.Schema.