0

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如果所有转换都成功(如果单个转换失败,则应导致)
  • 创建一个Either<E,List<B>>包含所有 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>>
    }
}
4

1 回答 1

2

有一个函数traverseEither可以让你做这些操作。

public inline fun <E, A, B> Iterable<A>.traverseEither(f: (A) -> Either<E, B>): Either<E, List<B>>

对于A中的每个值,Iterable它将调用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() }
    }

它也存在ValidatedOptionhttps://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/kotlin.collections.-iterable/index.html#extensions-for-kotlincollectionsiterable

您还可以在 Arrow Fx Coroutines 中找到并行变体

于 2021-09-15T14:20:57.453 回答