not sure if I'm missing it somewhere, but is there...
# arrow
s
not sure if I'm missing it somewhere, but is there a RaiseDSL builder for IorNel that automatically defines concatenating the error list? or just the regular
ior(...) {}
one?
s
That builder seems to indeed be missing @Sam Pengilly
s
Would probably also be good to have a few more examples around Ior, like how to idiomatically call some functions that return an Either, if they're the Right case use the value, and if they're the Left case use a default value and append the error into the IorNel list. It's not completely clear looking at scopes like IorRaise how that should be done, manually it seems at the moment? Maybe some overloads to bind in that scope or the Either.toIor() extension?
I'd be happy to help work on it, but it feels like it needs some API guidance
s
You should be able to call
bind
on
Either
in
Ior
. Doesn't that work? ๐Ÿค”
s
Hmmm, I didn't look deep enough, I assumed bind on an either in an Ior would trigger the short circuit Left case and not the Both case
s
Sure, I'd be happy to help with guidance for anyone that wants to contribute! โ˜บ๏ธ In #arrow-contributors, or in DM. I'm out on PTO soon, so might be slow to respond in next month.
Yes, if you bind on
Left
it does short-circuit but we could also figure out some API that allows for accumulation if providing a default value as you say. That'd be pretty neat
๐Ÿ‘ 1
s
Yea, the accumulation approach is what I'm interested in. Dealing with cases where say one function it only makes sense that it succeeds or fails (so either), but then having another function that calls a bunch of either returning functions, some of them might need to trigger a short circuit, but the rest can be recovered and we want to accumulate the error to log
s
Yes, that's exactly where
Ior
shines
Polishing that API, and adding that as documentation on the website would be super awesome! I'd love to help you if you're up for adding that
s
I'll have a think about how to approach it. Maybe something like
bindOrAccumulate
on Either inside an
IorRaise
scope, a clear operation that will bind a Right value or accumulate the Left value into a Both in the Ior rather than short circuiting. Thoughts?
s
That's probably a good name, but it's so long for that operation ๐Ÿ˜ข ๐Ÿ˜…
s
Just a bit
Another approach might just be to add a lambda parameter to Either.bind inside of IorRaise where the caller can say what they want to happen. But I feel like ergonomically that is probably worse, resulting in typing/intellisensing two method names instead of one slightly longer one
Actually... Another option, do something similar to
ignoreErrors {}
and define the semantics of the operation in the builder... So you might have an
ior {}
builder that binds eithers by short circuiting, but also providing an
iorAccumulateErrors {}
builder which doesn't short circuit and accumulates every error on bind.
For mixed behaviour it's possible to nest those builders in the same way someone might nest
nullable {}
,
either {}
, etc
Or something like the
recover
function inside
NullableRaise
.
Copy code
iorNel {
    // Recovers to null and accumulates the error in the Left case
    val value = eitherFunc().recover { null }
}
Actually that exists currently in IorRaise, just not as an extension on Either, as something that takes its own Raise block
It doesn't seem to accumulate the error though
s
also providing an
iorAccumulateErrors {}
builder which doesn't short circuit and accumulates every error on bind.
That wouldn't work because what do you provide on the left hand side of
bind
.
Copy code
val either: Either<String, Int> = "fail"
iorAccumulateErrors(String::plus) {
  val x: Int = either.bind()
  x + 1
}
You cannot accumulate, and continue here.
๐Ÿ‘ 1
recover
is probably confusing too, there is
recover
in
ior
but it ignores the error since you recovered from it.
๐Ÿ‘ 1
resulting in typing/intellisensing two method names instead of one slightly longer one
The first that came to mind for me was
bindOrGet
but I think that's not a good name
s
So
bindOrAccumulate
is probably still the best option? ๐Ÿ˜…
s
Ye, I think so ๐Ÿ˜…
Or
getAndAccumulate
๐Ÿค”
s
Yea, that would also work, maybe be a bit clearer
s
@Alejandro Serrano Mena might have some good ideas, but we can also discuss it further in a PR
s
I'll see how it plays out in my project with some local extension functions, see how it feels.
๐Ÿ‘Œ 1
Then submit if it seems alright
s
Awesome, thank you