如何在 Kotlin 中有效地展平 Either 列表

How to efficiently flatten a list of Either in Kotlin

我有一个类似这样的列表 List<Either<Failure, List<MyResult>>>,我想使用 Arrow-kt 将其展平为 Either<Failure, List<MyResult>>,但我尝试过的所有内容看起来都很笨拙,最终遍历列表两次。 感觉应该有更好的方法,但我想不通。 这是我现在拥有的一个人为的例子:

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() 

欢迎提出任何建议!

奖金问题:如果其中一个返回 Left,有没有捷径 things.map { } 的方法?

您要查找的函数是sequence

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

这将在第一个 Failure(如果有的话)和 return 上短路,或者给你所有的 MyResult 作为列表。

fix()map { it.fix() } 是必需的,因为 Arrow 对更高种类的类型进行了仿真。