Yannick Lazzari
08/12/2022, 12:25 AMValidated
vs. ValidatedNel
). The tutorial and most (or even all) examples I've seen on using the Validated
type declare all validation functions using ValidatedNel
type, even if the function only really ever returns a single error. For instance, a string field validation function that checks the length will either return a (single) length validation error, or the valid string, but the error is wrapped in the Nel
. And the only reason I can think of is because when zipping the validated types together, one can simply do
val someEntity: Validated<DomainError, SomeEntity> =
validateField1()
.zip(SemiGroup.nonEmptyList(),
validateField2(),
validateField3()) { (v1, v2, v3) -> SomeEntity(v1, v2, v3) }
i.e. not worry about dealing with Validated
vs. ValidatedNel
. I personally think the semantics are not accurate for these validation functions as we're false advertising that there could be multiple errors returned by each validation function. I think we should use the Nel
type when the function can truly return multiple errors, otherwise you should stick with Validated
. When zipping all your validated types together, it's really trivial to "sprinkle" a little toValidatedNel
here and there to then accumulate all the errors together:
val someEntity: Validated<DomainError, SomeEntity> =
validateField1SingleError().toValidatedNel()
.zip(SemiGroup.nonEmptyList(),
validateField2MultipleErrors(),
validateField3SingleError().toValidatedNel()) { (v1, v2, v3) -> SomeEntity(v1, v2, v3) }
Really nitpicking here, but I'm just curious to get other people's thoughts. Thanks!simon.vergauwen
08/12/2022, 7:21 AMValidatedNel
and I also typically only have a single error in my actual validation function.
Also I think that explicitly converting is not bad perse. Perhaps we can also expose zipNel
that allows passing Validated
but returns ValidatedNel
.
If you're up for making a ticket on Github that would be really appreciated 🙏
For Arrow 2.0 we're also thinking about the docs, but reducing the API and improving API will really help is improve the docs in a major way I think.Yannick Lazzari
08/12/2022, 12:35 PMYannick Lazzari
08/12/2022, 12:43 PMValidated<SomeErrorAdt, A>
, it should be Validated<SpecificErrorAdtInstance, A>
? So from the error handling tutorial, it would be
private fun FormField.contains(needle: String): Validated<DoesNotContain, FormField> =
if (value.contains(needle, false)) valid()
else ValidationError.DoesNotContain(needle).invalid()
instead of
private fun FormField.contains(needle: String): ValidatedNel<ValidationError, FormField> =
if (value.contains(needle, false)) validNel()
else ValidationError.DoesNotContain(needle).invalidNel()
? That's even more closer to what the function actually does. It doesn't just return any of the ValidationError
, it can only return the DoesNotContain
error. You can still compose that with any other validation functions whose return type either use ValidationError
because they can truly possibly return a subset of the subclasses, or with functions that also use another specific subclass.simon.vergauwen
08/12/2022, 12:49 PMYannick Lazzari
08/12/2022, 12:58 PM