Repository F# setup
open Reified
open Reified.Refinements
open Reified.Result
open Reified.Schema.JsonQuickstart
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
open Reified.Result
open Reified.ResultDSL
ReifiedResultReified.ResultDSLThe concise result vocabulary: the result { } computation expression, its accumulating result.list { } / result.array { } variants, and the lightweight admission functions (okIf, failIf, require, orError, mapError). Optional and opt-in, in the same shape as Reified.DataDSL, Reified.ConstraintDSL, and Reified.SchemaDSL: open Reified.Result for Result, then open Reified.ResultDSL for this vocabulary. Deliberately small: generic combinators such as map, bind, orElse, tap, and the traversal helpers stay qualified as Result.map, Result.bind, and so on.
The package works with the standard F# Result<'value, 'error> — it does not wrap or replace it. What it supplies is
the vocabulary around it:
| Concern | API | Returns |
|---|---|---|
Turn an option, nullable, or TryParse tuple into a Result |
Result.orError, Result.fromTry |
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
type QuantityError =
| InvalidInteger of string
| NotPositive of int
let quantity raw =
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 step's own failure is mapped into one deliberate application error type at the bind site.
Collect independent failures
let! fails fast; and! accumulates. The boundary is the compiler's, not a setting:
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.