Good day. I have a function which returns an Eithe...
# arrow
j
Good day. I have a function which returns an Either<DomainError, Id> which i need to invoke in a loop for a few times. What would be the best way to implement this loop taking into account that when a Either.Left<DomainError> is returned then the loop should stop?
s
You can do parSequence and use takeWhile to check if it is left or right. If you are using arrow-fix-coroutines
👍🏼 1
t
Copy code
either{
    someData.map{ yourFuncThatReturnsEither(it).bind() }
}
👍🏼 1
s
There is also
Either.tailRecM
, which has a bit of a confusing signature (particularly when dealing with Either). https://arrow-kt.io/docs/apidocs/arrow-core-data/arrow.core/-either/tail-rec-m.html If the type you're working with is
Either<DomainError, Id>
, the type signature is something like:
Copy code
<A> Either.tailRecM(repeatedValue: A, (A) -> Either<DomainError, Either<A, Id>>) : Either<DomainError, Id>
☝️ 3
The idea being that you provide the initial value of type
A
(which can be any type), and it is repeatedly given to the provided function, which is expected to return either a
Left<DomainError>
in the case of an error,
Right<Left<A>>
if you need to loop again with a new
A
, or a
Right<Right<Id>>
when you're done.
The benefit of
tailRecM
is that it should be stack safe.
👍🏼 1
p
you’ve been given all 3 options: sequence/parSequence, a
tailrec suspend fun
where you use
either { }
, or
tailrecM
j
@Satyam Agarwal Can you show an example of using
parSequence
and
takeWhile
as you recommend? Thanks.
s
Copy code
listOf(1,2,3,5)
            .map { element ->
                suspend { doSomethingWithElement(element) }
            }
            .parSequenceN(semaphoreLimit)
            .takeWhile { p -> p.isRight() }
its raw but I basically changed real use case to this
@julian
j
Thank you! @Satyam Agarwal
j
Thanks for the feedback