I have a list something like this List<Either<Failure, List<MyResult>>> and would like to flatten it to Either<Failure, List<MyResult>> using Arrow-kt but everything I've tried seems pretty clunky and ends up traversing the list twice.
It feels like there should be a better way but I can't figure it out.
Here's a contrived example of what I have now:
val things : List<MyThing> = /* some stuff */
val results : List<Either<Failure, List<MyResult>>> = things.map { doThingThatReturnsEither(it) }
val successes : List<MyResult> = results.mapNotNull { it.orNull() }.flatten()
val firstFailure : Failure? = results.mapNotNull { it.swap().orNull() }.firstOrNull()
return firstFailure?.let {it.left()} ?: success.right()
Any suggestions welcome!
Bonus question: is there a way to shortcut things.map { } if one of them comes back with a Left?
The function you are looking for is
sequencethis will short circuit on the first
Failure(if any) and return it as left, or give you all ofMyResultas list.the
fix()andmap { it.fix() }is needed because of Arrow's emulation of higher kinded types.