Interesting behaviour of `accumulate`: ```fun foo(...
# arrow-contributors
y
Interesting behaviour of `accumulate`:
Copy code
fun foo(): Either<Nothing?, Int> = accumulate(::either) {
  accumulate(null)
  return@foo 42.right()
}
This results in
Right(42)
, while the similar:
Copy code
fun foo() = accumulate(::either) {
  accumulate(null)
  42
}
results in
Left(null)
Should this be the behaviour? The same behaviour happens with
raise
as well:
Copy code
fun foo() = either {
  accumulate {
    accumulate(null)
    this@either.raise(42)
  }
}
a
Yes, that is expected. If you go outside of the scope, you're on your own. In fact, that the compiler forces you to write
42.right()
(and not just
42
shows that even the types are different
y
Sometimes the
.right()
isn't required either:
Copy code
context(_: Raise<NonEmptyList<Unit>>)
fun foo(): Int {
  accumulate {
    accumulate(Unit)
    return 42
  }
}
// vs 
context(_: Raise<NonEmptyList<Unit>>)
fun foo(): Int {
  return accumulate {
    accumulate(Unit)
    42
  }
}
It should probably be documented that non-local return from
accumulate
behaves differently from returning normally. After some thought, this might not be as unintuitive as I initially thought. My intuition was viewing
accumulate
raising any accumulated errors as a
finally
action of sorts, but perhaps that's not what a user immediately thinks. My (mostly mental) attempts at changing this behaviour have failed. We'd need to somehow differentiate between the
Raise<NonEmptyList<Error>>
that we're `accumulate`ing into, vs any outer
Raise
. It's likely possible using an intermediary
withError
or something like that.