I’m trying to build an object composed of other de...
# arrow
j
I’m trying to build an object composed of other dependencies, each dependency is obtained through a function returning
Either<Error, x>
, I got it too work but the code is rather cumbersome and difficult for anyone else to figure out quickly. This is a simplified version, but it works the same way :
Copy code
class A
class B
class C(
    val val1: String,
    val val2: String,
    val val3: String,
    val a: A,
    val b: B,
)

fun getA(val1: String): Either<Exception, A> = Either.Right(A())
fun getB(val1: String): Either<Exception, B> = Either.Right(B())
fun getCs(): Either<Exception, List<CBuilder>> = Either.Right(listOf(CBuilder("val1", "val2", "val3")))

class CBuilder(
    val val1: String,
    val val2: String,
    val val3: String,
)

class EitherTest {

    @Test
    fun buildC() {
        getCs().flatMap { builders ->
            builders.map { builder ->
                getA(builder.val1).flatMap { a ->
                    getB(builder.val1).map { b ->
                        C(builder.val1, builder.val2, builder.val3, a, b)
                    }
                }
            }.sequenceEither()
        }
    }
}
Is there a way to simplify the two first
map
in one operator, and is there a way to avoid consequent nesting of
map
and
flatmap
?
s
Hey @jean, You can use `Either`’s computation blocks.
either.eager { }
is what you would use here, or
either { }
if you’re inside
suspend
.
Copy code
either.eager {
  val builders = getCs().bind()
  builders.map { builder ->
    val a = getA(builder.val1)
    val b = getB(builder.val1)

    C(
       builder.val1,
       builder.val2,
       builder.val3,
       a,
       b
    )
  }.sequenceEither().bind()
}
j
I suppose I should also use
bind()
after
getA
and
getB
? Otherwise they are still of type
Either<Error, x>
but thanks, that looks much better than the all map/flatmap mess I had
and I also had to specify
either.eager<Exception, List<C>>
for the compiler to be happy