Arrow-kt:如何将 Either<E, List<Either<E,A>>> 变成 Either<E, List<B>>
Posted
技术标签:
【中文标题】Arrow-kt:如何将 Either<E, List<Either<E,A>>> 变成 Either<E, List<B>>【英文标题】:Arrow-kt: how to turn an Either<E, List<Either<E,A>>> into Either<E, List<B>> 【发布时间】:2021-11-10 15:19:42 【问题描述】:我从函数调用中收到Either<E, List<A>>
,需要将List<A>
转换为List<B>
。每个A的转换返回一个Either<E,B>
,所以我的结果是一个Either<E, List<Either<E,B>>>
。如何将Either<E, List<Either<E,B>>>
变成Either<E, List<B>>
,
Either.Left
)
创建一个包含所有 B 的 Either<E,List<B>>
,其中转换成功并忽略失败的 AtoB 转换
下面是一个小代码sn-p:
fun getListOfA(): Either<Exception, List<A>>
TODO()
fun A.transformAtoB(): Either<Exception, B>
TODO()
fun getListB(): Either<Exception, List<B>>
return getListOfA().map
// this is now Either<Exception, List<Either<Exception, B>>>
listOfA -> listOfA.map it.transformAtoB()
// ????? => Either<E, List<B>>
【问题讨论】:
【参考方案1】:有一个名为traverseEither
的函数允许您执行这些操作。
public inline fun <E, A, B> Iterable<A>.traverseEither(f: (A) -> Either<E, B>): Either<E, List<B>>
对于Iterable
中A
的每个值,它将调用f
,如果所有结果都是Either.Right
,则结果为Either.Right<List<B>>
,否则将导致第一个Either.Left<E>
它遇到了。
所以我们可以重写你的sn-p:
fun getListOfA(): Either<Exception, List<A>> = TODO()
fun A.transformAtoB(): Either<Exception, B> = TODO()
fun getListB(): Either<Exception, List<B>> =
getListOfA().flatMap listOfA ->
// this is now Either<Exception, List<Either<Exception, B>>>
listOfA.traverseEither it.transformAtoB()
它也存在于Validated
、Option
等https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/kotlin.collections.-iterable/index.html#extensions-for-kotlincollectionsiterable
您还可以在 Arrow Fx Coroutines 中找到并行变体
【讨论】:
.map 需要更改为 .flatMap 才能得到 EithertraverseOption
、traverseValidated
等,都可以在帖子分享的链接中找到。
很抱歉,我没有看到任何 traverseOption()。我之前阅读了链接页面,但描述中也没有 traverseOption。有一个 traverse()、traverseEither() 和 traverseValidated()。在 List 上,我只能执行 traverseEither/traverseValidated。我想在这里包含另一个库吗?我可以将 filterOption() 应用于 List
抱歉,traverseOption
仅在 0.13.3
和 1.0.0
将于 2021 年 9 月发布(写作本周晚些时候)之后添加。以上是关于Arrow-kt:如何将 Either<E, List<Either<E,A>>> 变成 Either<E, List<B>>的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Seq[Either[A,B]] 减少为 Either[A,Seq[B]]?
如何在flutter中将Either Right初始化为空值
将 Iterable[Either[A,B]] 减少为 Either[A, Iterable[B]]
在 Flutter 中解压 Option<Either<T,T>>