-
-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add function catch : Result ok err, (err -> a), (ok -> a) -> a
to standard library.
#6759
Comments
Thanks for your contribution @lalaithion!
numDict =
Dict.fromList [(1, "One"), (2, "Two")]
main =
numStr =
Dict.get numDict 3
|> Result.withDefault "Not found"
Stdout.line! numStr Feel free to correct me if I have this wrong! |
There are many cases where
Compare this to
I'm not sure what an implementation of this code would look like using |
I've played around with this and I'm liking this type of workflow more and more :) args = Arg.list!
arg =
List.get args 1
|> orElseR! "No command line args provided."
envVal =
Env.var arg
|> orElseT! "Env var $(arg) was not set."
int =
Str.toI64 envVal
|> orElseR! "Env var $(arg) was not an I64 number, but was: \"$(envVal)\""
Stdout.line! (Num.toStr int) With these helpers: orElseR = \result, errMsg ->
Result.mapErr result (\_ -> StrErr errMsg)
|> Task.fromResult
orElseT = \task, errMsg ->
Task.mapErr task (\_ -> StrErr errMsg) If we implement this proposal, we could also write it like this: Arg.list!
|> List.get args 1
|> orElseR! "No command line args provided."
|> Env.var
|> orElseT! "Env var was not set."
|> Str.toI64 envVal
|> orElseR! "Env var was not an I64 number."
|> Stdout.line! (Num.toStr int) Sidenote; I'm aware |
I don't think this has the same behavior? Both of the examples still need to match on the final value to figure out if an error occurred, and therefore handle the errors far away from the place they were generated. |
While writing multiple toy Roc programs, I always write this function very early. For example, in the following code in a dispatcher for a web server with multiple endpoints, I want to handle the error case by returning a 404 response.
Using
try
here would require that I turn errors into web responses far away from the result, for example:This has prior art in Haskell called
either
, in Rust calledmap_or_else
, and is a very similar pattern to returning early on error or exception in most imperative languages, e.g. in golangish pseudocode:Names considered:
catch
(using the already-existent reference to try catch blocks in the functiontry
),handle
(as in "handling" the error),result
(similar to Haskell'seither
naming),mapOrElse
(taken from Rust),earlyReturn
(similar to imperative languages). In the end I don't love any of these names, buthandle
orcatch
are my favorites.Reasons not to add this: It's a four-line implementation and any methods added at this point may become less useful if the language evolves in an unexpected direction, and removing things from the standard library is painful even if backwards compatibility is not promised yet.
Implementation:
The text was updated successfully, but these errors were encountered: