FSharp Validations is a validation library designed with a functional first approach.
The library supports:
- The ability to create rules for properties using the
RuleFor<'a, 'b>
function - The ability to apply a list of rules to a propery using
Rule<'a>
- the ability to reuse validators using
ruleSetFor<'a, 'b>
- The creation of
RuleSets<'a> -> 'a ValidationResult
The rules can then be evaluated at any time thanks to the magic of currying.
open FSharp.Validations
type Foo = { Bar: string }
let validateFoo =
ruleSet [
ruleFor <@ _.Bar @> [
rule (fun x -> x.Length > 0) (Some "Length must be greater than 0")
rule (fun x -> x.Length < 10) (Some "Length must be less than 10") ] ]
let result = validateFoo { Bar = "Hello, World!" }
// result is Failure (map [("Bar", ["Value must be less than 10"])])
Rule sets can be reused by creating a RuleSet<'a>
and applying it to
a property using the ruleSetFor<'a, 'b>
function.
type Bar = { Value: string }
type Foo = { Bar: Bar }
let validateBar =
ruleSet [
ruleFor <@ _.Value @> [
rule (fun x -> x.Length > 0) (Some "Length must be greater than 0")
rule (fun x -> x.Length < 10) (Some "Length must be less than 10") ] ]
let validateFoo =
ruleSet [
ruleSetFor <@ _.Bar @> validateBar ]
Any resulting errors for Bar
will have a key of Bar.{propertyName}
.
A Success
represents the entity that has passed validations.
A Failure
represents a Map<string, string list>
where the key is
the property that failed and value is a collection of all the messages
attached to the failure upon validation.
let result = validateFoo { bar = "Hello, World!" }
match result with
| Success value -> printfn "%A" value
| Failure errors -> errors |> Map.iter (printfn "%s: %A")
A function is provided to convert any 'a -> 'a ValidationResult
to
an 'a IValidator
using the provided toValidator
function.
The resulting 'a IValidator
can be used for Dependency Injection.
open Microsoft.Extensions.DependencyInjection
type Foo = { Bar: string }
let validateFoo =
ruleSet<Foo> [ ruleFor <@ _.Bar @> [ notEmpty ] ]
let fooValidator = validateFoo |> toValidator
let result = fooValidator.Validate({ Bar = "Hello, World!" })
// Add to Dependency Injection
let services = ServiceCollection() :> IServiceCollection
services.AddScoped<Foo IValidator>(fun _ -> fooValidator) |> ignore
FSharp.Validations is subject to copywright @ 2025 Oneirosoft and other contributors under the MIT License.