How to efficiently flatten a list of Either in Kotlin

2.2k views Asked by At

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?

1

There are 1 answers

3
LordRaydenMK On BEST ANSWER

The function you are looking for is sequence

val res:Either<Failure, List<MyResult>> = results.sequence(Either.applicative())
    .fix()
    .map { it.fix() }

this will short circuit on the first Failure (if any) and return it as left, or give you all of MyResult as list.

the fix() and map { it.fix() } is needed because of Arrow's emulation of higher kinded types.