Question about how to combine `Either<>`s that are wrapped in Rx `Single`s.
This is the example, and it seems to work, but I wonder if there is an easier/more-concise/better way of doing this
There are these two functions:
fun getAccountKeys(): Single<Either<List<AccountKey>>>
and
fun getAccount(key: AccountKey): Single<DataModelResult<Account>>
We’d like to create the following function, that will use the two above
fun getAccounts(): Single<DataModelResult<List<Account>>>
(
DataModelResult<T>
=
Either<DataError, T>
)
This is one implementation of `getAccounts()`:
val result: Single<DataModelResult<List<Account>>> =
getAccountKeys()
.flatMap { listOfKeys: DataModelResult<List<AccountKey>> ->
val rxOfKeys: DataModelResult<Observable<AccountKey>> =
listOfKeys.map { Observable.fromIterable(it) }
val rxOfAccounts: DataModelResult<Observable<DataModelResult<Account>>> =
rxOfKeys.map { rxKey -> rxKey.flatMapSingle(::getAccount) }
val rxOfListOfAccounts: DataModelResult<Single<List<DataModelResult<Account>>>> =
rxOfAccounts.map { it.toList() }
val single: Single<DataModelResult<List<Account>>> = when (rxOfListOfAccounts) {
is Either.Left -> Single.just(rxOfListOfAccounts)
is Either.Right -> rxOfListOfAccounts.b.map { listOfAccounts: List<DataModelResult<Account>> ->
listOfAccounts.fold(emptyList<Account>().just(), ::concat)
}
}
single
}
return result
.. and this top-level concat function ..
fun <L, T> concat(result: Either<L, List<T>>, item: Either<L, T>): Either<L, List<T>> =
result.flatMap { list -> item.map { list + it } }
Is this the way to go or is there a more Arrow/Functional way to go (we use Arrow version
0.9.0
)?
Thank you!