I am just trying to play around with tasks to understand them better and see how can I can fit them into my pipeline and so far converting them into Result seems like the easiest and most natural way to me.
e.g. consider this
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br" }
import pf.Task
import pf.Stdout
main =
tsk = Task.result! (tskCheck 1)
rsp = tskHandle tsk
dbg rsp
Stdout.line! "Done"
tskHandle = \tsk ->
when tsk is
Ok value -> handleGoodCase value
Err err -> handleErrorCase err
handleGoodCase = \value ->
v = Num.toStr value
dbg "Everything is fine $(v)"
Good value
handleErrorCase = \error ->
v = Num.toStr error
dbg "Something went wrong $(v)"
Bad error
tskCheck = \input ->
if input == 0 then
Task.ok input
else
Task.err input
To me this seems like a more cleaner approach then mapErr and/or onErr and keeps everything consistent with the rest of the code that might have other Results as well. But I am not sure if encapsulating Task output in a Result is considered good or bad? Or is it just a matter of choice?
Using Task.result!
followed by a when
is a common pattern. I would however write this code differently, I'll play around with it a bit.
Thanks @Anton . Any pointers will be greatly appreciated. I am trying to learn and do things the right (preferred) way. :pray:
The example is quite artificial so perhaps I left out too much, anyway I'd say this is normal Roc style:
import pf.Task
import pf.Stdout
main =
when checkInput 1 |> Task.result! is
Ok checkedValue ->
Stdout.line! "Received input $(Num.toStr checkedValue)."
Err badValue ->
# exit code 1 to indicate failure
Task.err (Exit 1 "Received bad input $(Num.toStr badValue).")
# mock Task
checkInput = \input ->
if input == 0 then
Task.ok input
else
Task.err input
Yeah this is perfect @Anton .
I just wrote small functions because I was playing around with different aspects of Task and Result. But thank you so very much, this makes perfect sense. It's clean, clear, concise and uses Result.
Really appreciate it @Anton :heart:
Happy to help :)
A general note: I find that the longer and more complex your code gets (especially if errors are handled in many different ways), onErr
and mapErr
become more and more natural.
I think that result
is nice, but if used a lot, can lead to broken up code that is much harder to follow.
Thanks @Brendan Hansknecht , I will keep that in mind. I am also trying to find some open source projects/tools written in roc to review their code.
All of roc code seems pretty natural to me except Task. When working with Task, even small changes break my code. But I am trying to work with Task as much possible in various ways to get a grasp of it. :pray:
Last updated: Jul 06 2025 at 12:14 UTC