如何在 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 对更高种类的类型进行了仿真。
我有一个类似这样的列表 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 对更高种类的类型进行了仿真。