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>>
我从函数调用中收到 Either<E, List<A>>
,需要将 List<A>
转换为 List<B>
。每个Areturns一个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 转换
下面是一小段代码:
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>>
}
}
有一个名为 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>
。
所以我们可以重写您的代码段:
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 协程中找到并行变体
我从函数调用中收到 Either<E, List<A>>
,需要将 List<A>
转换为 List<B>
。每个Areturns一个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 转换
下面是一小段代码:
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>>
}
}
有一个名为 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>
。
所以我们可以重写您的代码段:
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 协程中找到并行变体