Result.flatten best practice

Hi everybody, quick question. Basically, how do I use Result.flatten properly?

I have a LoadResult that uses Result.Result

but then it gets called from a higher level that also has it’s own error

What’s the best practice to not end up with #ok(#ok(#ok(#err etc…

What I’d like to happen is that when I return #ok(Entity.load) it can tell if there’s an error and instead of #ok(#err) it’s just #err. I tried using flatten but I’m just not sure what the best practice is there, what if I add more layers? Do I just recursively flatten at the top level (actor) or flatten all the way up?

Thanks!

If I just return Entity.load that does fix the problem…

But since #ok() and #ok(#ok()) are both valid return types, I guess what im asking is how do I stop errors creeping through as I refactor code. I need something that ensures it’s always flattened and the compiler catches if it isnt.

I’m short on time right now but my intuition says to use Result.chain which “short-circuits” the first time you get an #err or calls the next function that takes the argument from #ok and also produces a Result.

This is working for us:

We really just don’t let that happen. Any function that returns a Result is handled. We have a standard Error object that has some data that can be passed on and incorporated in the next error. With this pattern we just don’t end up with that scenario because nothing that is in a result ever returns a result in #ok.

As an aside, Kusanagi has a key word called matchr that makes handling returning errs much easier:

let result  = matchr(my_function(), val, return #err("info")

compiles to 

let result = switch(myfunction()){
     case(#ok(val)){val};
     case(#err(err)){return #err(err)}};