Closed serras closed 4 months ago
File | Coverage [68.21%] |
---|---|
arrow-libs/resilience/arrow-resilience/src/commonMain/kotlin/arrow/resilience/Schedule.kt | 68.21% |
Total Project Coverage | 61.06% |
---|
I think I got it!! Actually variants using E
everywhere is all we need!
fun <E: Throwable, A> Schedule<E, *>.retry(...)
This works without the intermediate E: Throw: Throwable
because of the contravariance of Schedule
. That is, since E: Throwable
, then Schedule<Throwable, ...>: Schedule<E, ...>
, as needed for the function to apply. I think this gives great ergonomics, as shown by the tests:
s.retry { ... }
, the type E
is taken from the type of s
. So the behavior is that all the exceptions are retried.s.retry<IllegalStateException, _> { ... }
if you want a more concrete type to be filtered than the one coming from s
. Furthermore, we ensure that IllegalStateException
is indeed a subtype of the input to s
, as required.But you can also use s.retry<IllegalStateException, _> { ... } if you want a more concrete type to be filtered than the one coming from s. Furthermore, we ensure that IllegalStateException is indeed a subtype of the input to s, as required.
That's really nice ergonomics, also I have really underused _
. I need to used it more, would also be good to use _
more in the Arrow docs IMHO. It looks so much better.
This is an alternative approach to #3414, which I think gives us better ergonomics
The main changes are:
retryOrElseEither
function gets a new overload with aKClass<E>
parameter, which is used to make the instance checks. Thereified
versions call those withE::class
.Schedule<E, A>
and also aKClass<E>
. However, this shouldn't be the case, as the check forE
is actually used to filter out the desired cases.