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