如何在Kotlin中有效地展平任何一个列表
我有一个类似这样的列表,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
?
回答
您正在寻找的功能是 sequence
val res:Either<Failure, List<MyResult>> = results.sequence(Either.applicative())
.fix()
.map { it.fix() }
这将在第一个Failure
(如果有)上短路并将其返回到左边,或者给你所有的MyResult
列表。
在fix()
和map { it.fix() }
,是因为较高的kinded类型的箭的仿真的需要。
- I had to `flatten()` in the extra `map` to get my desired results but this is way better than what I had before thanks.