Michal Patejko
03/30/2023, 11:48 AMAlejandro Serrano Mena
03/30/2023, 11:57 AMdata class Person(val name: String, val age: Int)
sealed interface Problem {
object NameProblem
object AgeProblem
}
fun validName(name: String): Either<NameProblem, String> = TODO()
fun validAge(age: Int): Either<AgeProblem, Int> = TODO()
Alejandro Serrano Mena
03/30/2023, 11:57 AMAlejandro Serrano Mena
03/30/2023, 11:58 AMfun validPerson(name: String, age: Int): Either<Nel<Problem>, Person> =
either {
zipOrAccumulate(
{ validName(name).bind() },
{ validAge(age).bind() }
) { n, a -> Person(n, a) }
}
simon.vergauwen
03/30/2023, 12:10 PMvalidName
and validAge
can also be suspend
, and Either.zipOrAccumulate(validName(age), validAge(age)) { n, a -> Person(n, a) }
also exists.
The benefit of the DSL version that Alejandro showed is that it works for both Either<NonEmptyList<E>, A>
and Either<E, A>
in a single DSL. Whilst with the Either.zipOrAccumulate
version you can only combine Either
of the same type and need to manually call toEitherNel()
to turn Either<E, A>
into Either<NonEmptyList<E>, A>
.Michal Patejko
03/30/2023, 12:28 PMErik Dreyer
11/28/2023, 7:28 PMdata class Pet(val name: String)
data class Person(val name: String, val age: Int, val pet: Pet)
fun createPerson(val name: String, val age: Int, pet: EitherNel<Problem, Pet>) = either {
zipOrAccumulate(
{ validName(name).bind() },
{ validAge(age).bind() },
{ pet.bind() }
) { n, a, p -> Person(n, a, p)
}
Or, put another way, what's the best way to fully validate nested objects when constructing both of them?simon.vergauwen
11/29/2023, 9:32 AMErik Dreyer
11/29/2023, 3:16 PMzipOrAccumulate
You should be able to run this as a scratch file in IntelliJ. This is using Arrow 1.2.1
I have validated that both NonEmptyString
and FutureDate
both individually return Either.Left
with the provided inputs, but when combined into a wrapper type (MissingValidations
) only the FutureDate
validation is returnedsimon.vergauwen
11/30/2023, 7:18 AM@BuilderInference
, you need to use bindNel
for FutureDate.of
. I hope that helps
fun of (string: String, date: LocalDate): EitherNel<DomainError, MissingValidations> =
either {
zipOrAccumulate(
{ NonEmptyString.of(string).bind() },
{ FutureDate.of(date).bindNel() }
) { s, d -> MissingValidations(s, d) }
}
Erik Dreyer
11/30/2023, 2:21 PM