Hi, can you show me an example of how to use zipOr...
# arrow
m
Hi, can you show me an example of how to use zipOrAccumulate method using coroutines? Just basic accumulation of 2/3 eithers and returning lefts (or all lefts merged into single object) if there's any.
a
let’s suppose you have the following scenario:
Copy code
data 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()
then you can run both validations and accumulate any possible error by using
Copy code
fun validPerson(name: String, age: Int): Either<Nel<Problem>, Person> = 
  either {
    zipOrAccumulate(
      { validName(name).bind() },
      { validAge(age).bind() }
    ) { n, a -> Person(n, a) }
  }
s
Here
validName
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>
.
m
Thank you! So easy!
e
I'm a little late to the game here. Does this mechanism chain to subobjects? For instance, extending the example above...
Copy code
data 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?
s
I would use the technique you propose here @Erik Dreyer, that is a great way to split up validation into smaller pieces! Splitting into seperate pieces, and functions is always a great option IMO to simplify code
thank you color 1
e
@simon.vergauwen Could you take a look at this snippet? Either I'm doing something wrong, or there's a possible bug in
zipOrAccumulate
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 returned
s
Hey @Erik Dreyer, It's an issue we currently have with
@BuilderInference
, you need to use
bindNel
for
FutureDate.of
. I hope that helps
Copy code
fun of (string: String, date: LocalDate): EitherNel<DomainError, MissingValidations> =
    either {
        zipOrAccumulate(
            { NonEmptyString.of(string).bind() },
            { FutureDate.of(date).bindNel() }
        ) { s, d -> MissingValidations(s, d) }
    }
e
ahh, nice. Didn't know about that. Thank you.
737 Views