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
sequence
this will short circuit on the first
Failure
(if any) and return it as left, or give you all ofMyResult
as list.the
fix()
andmap { it.fix() }
is needed because of Arrow's emulation of higher kinded types.