Appearance
aivi.validation
Utilities for working with Validation E A — like Result, but with an accumulation-oriented applicative path for independent failures. The current executable accumulation surface is zipValidation, which combines two Validation (NonEmptyList E) values and collects errors from both sides.
When you want the ambient prelude surface, these same operations are re-exported as isValid, isInvalid, validationGetOrElse, validationMapErr, validationToResult, validationFromResult, validationToOption, validationMap, validationAndThen, zipValidation, and validationFold.
aivi
use aivi.validation (
Errors
isValid
isInvalid
getOrElse
mapErr
toResult
fromResult
toOption
map
andThen
zipValidation
fold
)At a glance
| Export | Type | Use it for |
|---|---|---|
Errors E | NonEmptyList E | Canonical accumulated error carrier |
isValid | Validation E A -> Bool | Check whether validation succeeded |
isInvalid | Validation E A -> Bool | Check whether validation failed |
getOrElse | A -> Validation E A -> A | Unwrap with a fallback value |
mapErr | (E1 -> E2) -> Validation E1 A -> Validation E2 A | Transform only the error side |
toResult | Validation E A -> Result E A | Convert to Result |
fromResult | Result E A -> Validation E A | Convert from Result |
toOption | Validation E A -> Option A | Discard errors and keep the value when valid |
map | (A -> B) -> Validation E A -> Validation E B | Transform only the valid side |
andThen | (A -> Validation E B) -> Validation E A -> Validation E B | Chain dependent validation steps |
zipValidation | Validation (NonEmptyList E) A -> Validation (NonEmptyList E) B -> Validation (NonEmptyList E) (A, B) | Accumulate independent failures from both sides |
fold | (E -> B) -> (A -> B) -> Validation E A -> B | Collapse a validation to one output type |
Start with this table when you want the export inventory first; the detailed sections below explain the individual helpers in more depth.
Errors
A type alias for a non-empty list of errors. Used as the error carrier in zipValidation.
aivi
type Errors E = NonEmptyList EErrors E guarantees at least one error is present when a validation fails. Import NonEmptyList from aivi.nonEmpty to construct values of this type.
isValid
Returns True if the validation holds a value.
Type: opt:(Validation E A) -> Bool
aivi
use aivi.validation (isValid)
type Validation Text Int -> Bool
func passed = v =>
isValid visInvalid
Returns True if the validation has failed.
Type: opt:(Validation E A) -> Bool
aivi
use aivi.validation (isInvalid)
type Validation Text Int -> Bool
func rejected = v =>
isInvalid vgetOrElse
Extracts the value from Valid, or returns the fallback if Invalid.
Type: fallback:A -> opt:(Validation E A) -> A
aivi
use aivi.validation (getOrElse)
type Validation Text Int -> Int
func safeValue = v =>
getOrElse 0 vmapErr
Transforms the error inside Invalid, leaving Valid untouched.
Type: transform:(E1 -> E2) -> opt:(Validation E1 A) -> Validation E2 A
aivi
use aivi.validation (mapErr)
type Text -> Int
func toCode = message =>
42
type Validation Text Int -> (Validation Int Int)
func withErrorCode = v => v
|> mapErr toCodetoResult
Converts a Validation to a Result. Valid value becomes Ok value; Invalid err becomes Err err.
Type: opt:(Validation E A) -> Result E A
aivi
use aivi.validation (toResult)
type Validation Text Int -> (Result Text Int)
func asResult = v =>
toResult vfromResult
Converts a Result to a Validation. Ok value becomes Valid value; Err error becomes Invalid error.
Type: opt:(Result E A) -> Validation E A
aivi
use aivi.validation (fromResult)
type Result Text Int -> (Validation Text Int)
func asValidation = r =>
fromResult rtoOption
Converts a Validation to an Option, discarding any errors. Valid value becomes Some value; Invalid becomes None.
Type: opt:(Validation E A) -> Option A
aivi
use aivi.validation (toOption)
type Validation Text Int -> (Option Int)
func justValue = v =>
toOption vmap
Transforms the value inside Valid using a function, leaving Invalid untouched.
Type: transform:(A -> B) -> opt:(Validation E A) -> Validation E B
aivi
use aivi.validation (map)
type Int -> Int
func double = n =>
n * 2
type Validation Text Int -> (Validation Text Int)
func doubleValid = v => v
|> map doubleandThen
Chains a Validation-returning function over a Valid value. If the input is Invalid, the error is propagated without calling the function.
Unlike zipValidation, andThen stops at the first failure and does not accumulate errors.
Type: next:(A -> Validation E B) -> opt:(Validation E A) -> Validation E B
aivi
use aivi.validation (andThen)
type Int -> (Validation Text Int)
func ensurePositive = n => n > 0
T|> Valid n
F|> Invalid "must be positive"
type Validation Text Int -> (Validation Text Int)
func validateCount = v => v
|> andThen ensurePositivezipValidation
Combines two validations into one that holds a tuple of both values. If either or both sides are Invalid, all errors are accumulated into a NonEmptyList. This is the primary tool for parallel form validation.
Type: left:(Validation (NonEmptyList E) A) -> right:(Validation (NonEmptyList E) B) -> Validation (NonEmptyList E) (A, B)
aivi
use aivi.validation (zipValidation)
use aivi.nonEmpty (
NonEmptyList
singleton
)
type FieldError =
| EmptyName
| InvalidAge
type Text -> (Validation (NonEmptyList FieldError) Text)
func validateName = name => name
||> "" -> Invalid (singleton EmptyName)
||> _ -> Valid name
type Int -> (Validation (NonEmptyList FieldError) Int)
func validateAge = age => age > 0
T|> Valid age
F|> Invalid (singleton InvalidAge)
type Text -> Int -> (Validation (NonEmptyList FieldError) (Text, Int))
func validateForm = name age =>
zipValidation (validateName name) (validateAge age)If both validateName and validateAge fail, the result is Invalid containing both EmptyName and InvalidAge in a single list.
fold
Collapses a Validation to a single value by applying onValid to Valid or onInvalid to Invalid.
Type: onInvalid:(E -> B) -> onValid:(A -> B) -> opt:(Validation E A) -> B
aivi
use aivi.validation (fold)
use aivi.nonEmpty (
NonEmptyList
length
)
type NonEmptyList Text -> Int
func countErrors = errors =>
length errors
type Int -> Int
func identity = n =>
n
type Validation (NonEmptyList Text) Int -> Int
func scoreOrErrorCount = v =>
fold countErrors identity v