Interface Validated<E,T>
- All Known Implementing Classes:
Validated.Invalid, Validated.Valid
Result, but the Invalid case accumulates ALL errors instead of
short-circuiting on the first one.
Pick Validated over Result when you want every reason a form,
config, or DTO is invalid, not just the first.
Validated<String, Form> v = nameField.zip(emailField, Form::new);
// If both invalid: v carries both error messages.
Convert to/from Result when you need to switch behaviour mid-pipeline.
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic interfaceThe binding handle passed toaccumulate(Function).static interfaceA value bound inside anaccumulateblock, not yet unwrapped.static final recordstatic final record -
Method Summary
Modifier and TypeMethodDescriptionstatic <E,T> Validated <E, T> accumulate(Function<? super Validated.Accumulator<E>, ? extends T> block) Error-accumulation DSL: validate several independent pieces as straight-line code and surface every failure at once.default <R> Rfold(Function<? super NonEmptyList<E>, ? extends R> onInvalid, Function<? super T, ? extends R> onValid) Fold both cases into a single value.static <E,T> Validated <E, T> fromResult(Result<E, T> r) Lift aResultinto a single-errorValidated.static <E,T> Validated <E, T> invalid(NonEmptyList<E> errors) Build a failure carrying one or more accumulated errors.static <E,T> Validated <E, T> invalid(E error) Build a failure carrying a single error.default booleantrueif this isValidated.Invalid.default booleanisValid()trueif this isValidated.Valid.Transform the success value; preserve the errors.Transform every error in the batch; preserve the valid value.default Result<NonEmptyList<E>, T> toResult()Convert back into aResult.static <E,T, R> Validated <E, NonEmptyList<R>> traverse(NonEmptyList<T> items, Function<? super T, ? extends Validated<E, R>> parse) traverse, preserving non-emptiness.Validate every element of a list with one function, accumulating every failure: the accumulative "traverse".static <E,T> Validated <E, T> valid(T value) Build a success.zip(Validated<E, U> other, BiFunction<? super T, ? super U, ? extends R> f) Combine twoValidateds into one via a binary function.
-
Method Details
-
valid
Build a success. -
invalid
Build a failure carrying a single error. -
invalid
Build a failure carrying one or more accumulated errors. -
fromResult
-
traverse
static <E,T, Validated<E,R> List<R>> traverse(List<? extends T> items, Function<? super T, ? extends Validated<E, R>> parse) Validate every element of a list with one function, accumulating every failure: the accumulative "traverse".Validated.Validof the parsed elements (in input order) only if every element passed; otherwiseValidated.Invalidcarrying the errors of every failed element, in input order.An empty list is trivially
Validof an empty list. When emptiness is itself a failure, pair withNonEmptyList.fromList, or use theNonEmptyList overload, which carries non-emptiness through: non-empty in, non-empty out. -
traverse
static <E,T, Validated<E, NonEmptyList<R>> traverseR> (NonEmptyList<T> items, Function<? super T, ? extends Validated<E, R>> parse) traverse, preserving non-emptiness. -
accumulate
static <E,T> Validated<E,T> accumulate(Function<? super Validated.Accumulator<E>, ? extends T> block) Error-accumulation DSL: validate several independent pieces as straight-line code and surface every failure at once. TheValidatedcounterpart ofResult.binding, and the arity-free alternative to chainedzipcalls.Inside the block,
acc.on(...)binds each validation and returns aValidated.Boundhandle. A failed binding records its errors and keeps going, so every validation runs. Unwrap the handles withValidated.Bound.value()once everything is bound; the first unwrap of a failed binding ends the block. The result isValidated.Validof the block's return value only if no binding failed, otherwiseValidated.Invalidwith all errors in binding order:Validated<Failure, Form> form = Validated.accumulate(acc -> { var name = acc.on(validateName(raw)); // Invalid -> recorded, no abort var email = acc.on(validateEmail(raw)); // still runs var age = acc.on(validateAge(raw)); // still runs return new Form(name.value(), email.value(), age.value()); }); // form == Invalid([nameError, emailError, ageError]) if all three failedBind first, unwrap last. Interleaving (
acc.on(a).value()before bindingb) silently degrades to short-circuiting: a failed unwrap aborts before later validations bind. Dependent validations belong inResult.binding; this DSL is for independent ones.The abort uses the same private control-flow exception mechanism as
Result.binding(see ADR-1), with the same caveats: don't wrap unwraps in a catch-allcatch (RuntimeException e), and don't letBoundhandles escape the block. Nestedaccumulateblocks are safe: each abort carries the identity of the block that created it and unwinds to that block's boundary.- Parameters:
block- receives theValidated.Accumulatorand returns the composed value.- Returns:
Validated.Validof the block's return value, orValidated.Invalidcarrying all accumulated errors in binding order.
-
isValid
default boolean isValid()trueif this isValidated.Valid. -
isInvalid
default boolean isInvalid()trueif this isValidated.Invalid. -
map
-
mapErr
Transform every error in the batch; preserve the valid value. The accumulating counterpart ofResult.mapErr, typically used at the boundary to translate domain errors into API- or user-facing shapes without losing any of the batch. -
zip
default <U,R> Validated<E,R> zip(Validated<E, U> other, BiFunction<? super T, ? super U, ? extends R> f) Combine twoValidateds into one via a binary function.Error semantics (the key difference from
Result):- Both
Valid: appliesf, returnsValid<R>. - One
Invalid: errors propagate. - Both
Invalid: errors concatenate viaNonEmptyList.concat(NonEmptyList).
This is the
ap("applicative") combinator. Use to validate independent fields together and surface all problems at once. - Both
-
toResult
Convert back into aResult. The error side becomes the accumulated list so the caller can pattern-match on either a single error or a batch. -
fold
default <R> R fold(Function<? super NonEmptyList<E>, ? extends R> onInvalid, Function<? super T, ? extends R> onValid) Fold both cases into a single value.
-