Home > Software design >  Arrow-kt: how to turn an Either<E, List<Either<E,A>>> into Either<E, List<B&
Arrow-kt: how to turn an Either<E, List<Either<E,A>>> into Either<E, List<B&

Time:09-17

I receive an Either<E, List<A>> from a function call and need to transform the List<A> into a List<B>. The transformation of each A returns an Either<E,B>, so that my result is an Either<E, List<Either<E,B>>>. How can I turn the Either<E, List<Either<E,B>>> into an Either<E, List<B>>,

  • if all transformation succeeded (Should result in Either.Left, if a single transformation fails)
  • create an Either<E,List<B>> containing all Bs, for which the transformation succeeded and ignoring failed AtoB transformations

A little code snippet below:

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>>
    }
}

CodePudding user response:

There is a function called traverseEither that allows you to do these kind of operations.

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

For every value of A in the Iterable it will call f, and if all the results are Either.Right then it will result in Either.Right<List<B>> and otherwise it will result in the first Either.Left<E> it encounters.

So we can rewrite your snippet:

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() }
    }

It also exists for Validated, Option etc https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/kotlin.collections.-iterable/index.html#extensions-for-kotlincollectionsiterable

And you can also find parallel variants inside Arrow Fx Coroutines

  • Related