Philipp Mayer
01/17/2022, 5:25 PMEither
of type <List<Error>, Success>>
, how could I collect both of their lefts (if both are left).
My setup looks like this:
import arrow.core.Either
data class Error(val message: String)
data class Success(val data: Int)
data class SuccessSum(val success1: Success?, val success2: Success?)
fun myFunction(): Either<List<Error>, SuccessSum> {
val responseA = someNetworkCall()
val responseB = someNetworkCall()
return TODO()
}
fun someNetworkCall(aGivenParameter: Int = 1): Either<List<Error>, Success> {
TODO()
}
and I have the following possibilities regarding my return type:
it can either be:
• a list of errors originating from the first response
• a list of errors originating from the second response
• a list of errors originating from both responses
• SuccessSum
, my happy path
Is there any way to check if both eithers are null and if they are, merge their left values together into one list?
My happy path would then look like that:
fun myFunction(): Either<List<Error>, SuccessSum> {
val responseA = someNetworkCall()
val responseB = someNetworkCall()
/* Guard Clause checking for lefts here */
return SuccessSum(
success1 = responseA.orNull(),
success2 = responseB.orNull()
)
}
That’s at least my initial idea. I guess Validated
could be a better option but I didn’t look into it yet.
Thanks in advance! 🙂raulraja
01/17/2022, 8:20 PMtoValidatedNel
and zip
them together as shown in the https://arrow-kt.io/docs/patterns/error_handling/ in order to accumulate errors. Alternatively you may have your network calls return ValidatedNel
instead of Either
and then you can also use the bind
in either
blocks to treat the Validated
values as if they where Either
values.Philipp Mayer
01/18/2022, 7:55 AMimport arrow.core.Either
import arrow.core.ValidatedNel
import arrow.core.zip
data class Error(val message: String)
data class Success(val data: Int)
data class SuccessSum(val success1: Success?, val success2: Success?)
//my network call is now returning ValidatedNel<List<Error>, Success>
//this function merges both responses into an either
infix fun ValidatedNel<List<Error>, Success>.mergeWith(
leaseResponse: ValidatedNel<List<Error>, Success>,
): Either<List<Error>, SuccessSum> =
zip(leaseResponse) { firstSuccess, secondSuccess -> SuccessSum(firstSuccess, secondSuccess) }
.mapLeft { it.flatten() }
.toEither()
The thing that I’d like to remove is the mapLeft
+ ultimately returning an Nel<Error>
instead of a List<Error>
. Any hints on that?raulraja
01/18/2022, 11:03 AMList
which is not correct since you can’t never have an empty List of Errors, you either have errors or you don’t and it could be encoded like:raulraja
01/18/2022, 11:03 AMraulraja
01/18/2022, 11:04 AMValidatedNel
already implies the left is a NonEmptyList
so ValidatedNel<List…
is redundant and can be avoided. Your network services should just return ValidatedNel<Error, ..>
raulraja
01/18/2022, 11:05 AMValidated<NonEmptyList<Error>, ...>
which is the samePhilipp Mayer
01/18/2022, 11:06 AMPhilipp Mayer
01/18/2022, 11:06 AMraulraja
01/18/2022, 11:06 AMunsafeFromList
for cases where the list is handed to you and you are sure it has somethingPhilipp Mayer
01/18/2022, 11:06 AMraulraja
01/18/2022, 11:06 AM