Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Control.Validate

Validation as an algebraic effect.

Validate(e) is the computation-oriented companion to Data.Validation.Validation(e, a). A fatal refute(error) abandons the current validation branch. A non-fatal dispute(error) records an error but lets that branch continue. run_validate reports all recorded errors in encounter order, and tolerate turns fatal errors in a nested branch into a recoverable None so validation can continue elsewhere.

Unlike Haskell’s ValidateT, Prism does not give ordinary effectful sequencing a separate accumulating Applicative interpretation. Independent branches are run explicitly and wrapped in tolerate when validation should continue after a refutation; pure, already-computed validations can instead be combined with Data.Validation.validate2. Opt-in: not in Base.

Effects

Validate

effect Validate(e)
  never refute(e) : a
  dispute(e) : Unit

Errors raised while validating values of type e.

Functions and Values

run_validate

run_validate : forall e0 a b. (() -> a ! {Control.Validate.Validate(b), e0}) -> Data.Validation.Validation(b, a) ! {e0}

Run a validation computation. Any fatal or non-fatal errors make the result Invalid; only a completed computation with no errors is Valid.

run_validate(\() -> disputes(["too small", "odd"]))
Data.Validation.Invalid([too small, odd])

exec_validate

exec_validate : forall e0 a b. (() -> a ! {Control.Validate.Validate(b), e0}) -> List(b) ! {e0}

Run a validation computation and return its errors, or Nil on success.

disputes

disputes : forall a. (List(a)) -> Unit ! {Control.Validate.Validate(a)}

Raise each error as a non-fatal dispute, in list order.

tolerate

tolerate : forall e0 a b. (() -> a ! {Control.Validate.Validate(b), Control.Validate.Validate(b), e0}) -> Option(a) ! {Control.Validate.Validate(b), e0}

Make fatal errors in action recoverable. A refuted branch becomes None; a branch that completes returns Some(value), even if it raised disputes. All captured errors are re-raised as disputes in the outer validation, so the final run still fails unless another handler consumes them.

exec_validate(\() -> tolerate(\() -> refute("bad field")))
[bad field]