我從一個函式呼叫中收到一個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,對于這些B的轉換成功了,并且忽略了失敗的A到B的轉換 。
下面是一個小的代碼片斷:
fun getListOfA(): Either<Exception, List<A> > {
TODO()
}
fun A.transformAtoB(): Either<Exception, B> {
TODO()
}
fun getListB(): Either<Exception, List<B> > {
回傳getListOfA().map {
//現在是Either<Exception, List<Either<Exception, B>>>。
listOfA -> listOfA.map { it.transformAtoB() }
// ????? => Either<E, List<B>>
}
}
uj5u.com熱心網友回復:
有一個叫做traverseEither的函式允許你進行這類操作。
public inline fun <E, A, B> Iterable<A>.traverseEither(f: (A) -> Either<E, B>)。Either<E, List<B>>/code>
對于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 Coroutines里面找到并行的變體
。轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/308541.html
標籤:
