Pardon me for the stupid question. But I don't really understand what am I doing wrong:
This works:
ip = "127.0.0.1"
url = "http://\(ip)/win&T=2"
This does not
ip = "127.0.0.1"
Str.concat "IP: " ip
|> Stdout.line
url = "http://\(ip)/win&T=2"
with error
This looks like an operator, but it's not one I recognize!
12│ ip = "127.0.0.1"
13│ "IP: \(ip)"
14│ |> Stdout.line
15│
16│ url = "http://\(ip)/win&T=2"
^
I have no specific suggestion for this operator, see TODO for the full
list of operators in Roc.⏎
Slightly different code
12│ ip = "127.0.0.1"
13│> Stdout.line "IP: \(ip)"
14│>
15│> url = "http://\(ip)/win&T=2"
Looks like you are trying to define a function. In roc, functions are
always written as a lambda, like increment = \n -> n + 1.⏎
Stdout.line
constructs a Task
, but it doesn't run it right away. In order to do so and continue doing other stuff after, you can use Task.await
like this:
ip = "127.0.0.1"
{} <- Stdout.line "IP: \(ip)" |> Task.await
url = "http://\(ip)/win&T=2"
The type of Task.await
looks like this:
await : Task a b, (a -> Task c b) -> Task c b
It takes a Task
(in this case the one returned by Stdout.line ...
), and a callback which takes the value produced by running the Task
(in this case {}
, since printing doesn't produce any meaningful values) and returns the next Task
.
The <-
syntax is called Backpassing, and it's just a convenient way to pass a callback to a function without increasing the indentation level.
You could also write it like this without Backpassing:
ip = "127.0.0.1"
Stdout.line "IP: \(ip)" |> Task.await \{} ->
url = "http://\(ip)/win&T=2"
# The rest of your code...
Thanks! I was trying Task.await
but this was needed:
{} <- ...
I'm not yet completely understand why.
Ah, seems I need to tell Roc to "discard" I/O operation result.
Thanks again!
Dan has marked this topic as resolved.
Yes. If instead you used a Task
that produces values such as Stdin.line
, you'd give them a name instead of discarding them:
input <- Stdout.line |> Task.await
Last updated: Jul 06 2025 at 12:14 UTC