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

Quickstart

Reified.Result is a standalone leaf. Nothing else in Reified is required, and it depends on no other Reified package:

dotnet add package Reified.Result
Verified
open Reified.Result
open Reified.ResultDSL

The package works with the standard F# Result<'value, 'error> without wrapping or replacing it. It provides:

Concern API Returns
Turn a TryParse tuple into a Result, then name the error Result.fromTry, then Result.orError Result<'value,'error>
Compose dependent failures result { } Result<'value,'error>
Collect independent failures result.list { } with and! Result<'value,'error list>
Apply a fallible operation across a sequence Result.traverse, Result.sequence Result<'value list,'error>
Observe without changing the value Result.tap, Result.tapError Result<'value,'error>

Compose dependent steps

Verified
open System

type QuantityError =
    | InvalidInteger of string
    | NotPositive of int

let quantity (raw: string) =
    result {
        let! parsed =
            Int32.TryParse raw
            |> Result.fromTry
            |> Result.orError (InvalidInteger raw)

        let! positive =
            if parsed > 0 then Ok parsed else Error (NotPositive parsed)

        return positive
    }

Each failure maps to the application error type at its bind site.

Collect independent failures

let! fails fast; and! accumulates. The choice depends on the binding syntax:

Fragment
result.list {
    let! name = parseName input.Name
    and! age  = parseAge input.Age
    return name, age
}
// Error [ NameMissing; AgeNotANumber "x" ]

Everything inside one and! group is accumulated into a list. A later let! binds sequentially and fails fast, because it can depend on the earlier results. See Collecting every error for the exact boundary.

Where the other packages fit

This accumulation is flat: a list of your error values with no field identity and no path. Admitting values in the first place belongs to Constraints, while path-aware accumulated diagnostics over a whole structured input belong to Reified.Schema.

All of them return the standard F# Result, so these helpers work on their output, but none of them requires this package.

Continue