3

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

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

欢迎任何建议!

things.map { }额外的问题:如果其中一个人回来了,有没有捷径可走Left

4

1 回答 1

7

您正在寻找的功能是sequence

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

这将在第一个(如果有的话)短路Failure并将其作为左侧返回,或者将所有内容MyResult作为列表提供给您。

fix()和是必需的map { it.fix() },因为 Arrow 模拟了更高种类的类型。

于 2020-12-11T17:36:49.530 回答