The move to the new continuations API in Arrow brought with it a handy new function: shift
, in theory letting me get rid of ensure(false) { NewError() }
or NewError().left().bind()
constructs.
But I'm not sure how to properly use it. The documentation states that it is intended to short-circuit the continuation, and there are no conditionals, so it should always take the parameter, and (in either parlance) "make it a left value", and exit the scope.
So what is the type parameter B
intended to be used for? It determines the return type of shift
, but shift
will not return. Given no more context, B
can not be inferred, leading to this kind of code:
val res = either {
val intermediate = mayReturnNull()
if (intermediate == null) {
shift<Nothing>(IntermediateWasNull())
}
process(intermediate)
}
Note the <Nothing>
(and ignore the contrived example, the main point is that shift
s return type can not be inferred – the actual type parameter does not even matter).
I could wrap shift
like this:
suspend fun <L> EffectScope<L>.fail(left: L): Nothing = shift(left)
But I feel like that is missing the point. Any explanations/hints would be greatly appreciated.