Task
Task ok err
A Task represents an effect; an interaction with state outside your Roc program, such as the terminal's standard output, or a file.
forever : Task a err -> Task * err
Run a task that never ends. Note that this task does not return a value.
loop : state, (state -> Task [ Step state, Done done ] err) -> Task done err
Run a task repeatedly, until it fails with err or completes with done.
ok : a -> Task a *
Create a task that always succeeds with the value provided.
# Always succeeds with "Louis" getName : Task.Task Str * getName = Task.ok "Louis"
err : a -> Task * a
Create a task that always fails with the error provided.
# Always fails with the tag `CustomError Str` customError : Str -> Task.Task {} [CustomError Str] customError = \err -> Task.err (CustomError err)
attempt : Task a b, (Result a b -> Task c d) -> Task c d
Transform a given Task with a function that handles the success or error case and returns another task based on that. This is useful for chaining tasks together or performing error handling and recovery.
Consider a the following task;
canFail : Task {} [Failure, AnotherFail, YetAnotherFail]
We can use attempt to handle the failure cases using the following;
result <- canFail |> Task.attempt when result is Ok Success -> Stdout.line "Success!" Err Failure -> Stdout.line "Oops, failed!" Err AnotherFail -> Stdout.line "Ooooops, another failure!" Err YetAnotherFail -> Stdout.line "Really big oooooops, yet again!"
Here we know that the canFail task may fail, and so we use
Task.attempt to convert the task to a Result and then use pattern
matching to handle the success and possible failure cases.
await : Task a b, (a -> Task c b) -> Task c b
Take the success value from a given Task and use that to generate a new Task.
For example we can use this to run tasks in sequence like follows;
# Prints "Hello World!\n" to standard output. {} <- Stdout.write "Hello "|> Task.await {} <- Stdout.write "World!\n"|> Task.await Task.ok {}
onErr : Task a b, (b -> Task a c) -> Task a c
Take the error value from a given Task and use that to generate a new Task.
# Prints "Something went wrong!" to standard error if `canFail` fails. canFail |> Task.onErr \_ -> Stderr.line "Something went wrong!"
map : Task a c, (a -> b) -> Task b c
Transform the success value of a given Task with a given function.
# Succeeds with a value of "Bonjour Louis!" Task.ok "Louis" |> Task.map (\name -> "Bonjour \(name)!")
mapErr : Task c a, (a -> b) -> Task c b
Transform the error value of a given Task with a given function.
# Ignore the fail value, and map it to the tag `CustomError` canFail |> Task.mapErr \_ -> CustomError
fromResult : Result a b -> Task a b
Use a Result among other Tasks by converting it into a Task.
batch : Task a c -> Task (a -> b) c -> Task b c
Apply a task to another task applicatively. This can be used with
ok to build a Task that returns a record.
The following example returns a Record with two fields, apples and
oranges, each of which is a List Str. If it fails it returns the tag
NoFruitAvailable.
getFruitBasket : Task { apples : List Str, oranges : List Str } [NoFruitAvailable] getFruitBasket = Task.ok { apples: <- getFruit Apples |> Task.batch, oranges: <- getFruit Oranges |> Task.batch, }
result : Task ok err -> Task (Result ok err) *
Transform a task that can either succeed with ok, or fail with err, into
a task that succeeds with Result ok err.
This is useful when chaining tasks using the ! suffix. For example
# Path.roc checkFile : Str -> Task [Good, Bad] [IOError] # main.roc when checkFile "/usr/local/bin/roc" |> Task.result! is Ok Good -> "..." Ok Bad -> "..." Err IOError -> "..."