Behind the scenes it’s still a JS array, so it’s not actually immutable. If you see unit in the return type you’ll know it most likely mutates something
You can do the same thing using concat and an inner loop, I typically do something very similar in my codebase
let sequence = results => {
let rec loop = (i, oks) =>
switch results[i] {
| None => Ok(oks)
| Some(Ok(x)) => loop(i + 1, Js.Array.concat(oks, [x]))
| Some(Error(_) as e) => e
}
loop(0, [])
}
By the way, it is not the exact signature that you asked for, but I have found a function like this to be very useful in cases where you need to keep track of all the errors and not only the first one.
let combineErrors:
array<result<'ok, 'error>> => result<array<'ok>, array<'error>>
Quick question, as this has come up in other contexts: how do you end up with a array of result?
Generally, you use result when you care about the error, but pretty much any instance when you convert an array of result to a result of array you’re throwing away any info of what the error was.
So I would question the use of result to begin with: in addition to all that ceremony of carrying around all the error information, you end up throwing it away, which seems puzzling.
Others have given some examples, but another I have found helpful is parsing config files and other user input. Gather up all the errors the user made and dump them all to a log or however you want to handle them.
As for throwing data away, Result.fromArrayMap in my PR is somewhat lazy. It evaluates each input in turn for errors and stops calculating when an error is found.