Stream: beginners

Topic: Help with Task.await


view this post on Zulip Daniel Haehre (Oct 17 2023 at 13:11):

Hi, I just downloaded Roc and I am trying to get my head around it. Really like it so far :D

But I have encountered something that makes me wonder if I am doing something fundamentally wrong or if it is a bug.

I have modified the fizzbuzz example with basic-cli:

getNum : Task Str *
getNum =
    Task.await (Stdout.line "Enter a number: ") \_ -> Stdin.line

call : Task Str *
call =
    url = "https://example.com"
    _ <- Task.await (Stdout.line "Calling \(url)")

    request = {
        method: Get,
        headers: [],
        url,
        body: Http.emptyBody,
        timeout: NoTimeout,
    }

    Http.send request
        |> Task.onErr (\err -> err |> Http.errorToString |> Task.ok)

main =
    output <- Task.await call

    _ <- Task.await (Stdout.line "Got: \(output)")

    input <- Task.await getNum

    when Str.toI32 input is
        Err _ -> Stdout.line "Invalid input"
        Ok n ->
            List.range { start: At 1, end: At n }
            |> List.map fizzBuzz
            |> Str.joinWith "\n"
            |> Stdout.line

But running roc check I get the following:

This 2nd argument to await has an unexpected type:

32│>      output <- Task.await call
33│>
34│>      _ <- Task.await (Stdout.line "Got: \(output)")
35│>
36│>      input <- Task.await getNum
37│>
38│>      when Str.toI32 input is
39│>          Err _ -> Stdout.line "Invalid input"
40│>          Ok n ->
41│>              List.range { start: At 1, end: At n }
42│>              |> List.map fizzBuzz
43│>              |> Str.joinWith "\n"
44│>              |> Stdout.line

The argument is an anonymous function of type:

    Str -> Task {} *

But await needs its 2nd argument to be:

    Str -> Task {} *

I probably should add that removing the lines 32-34 makes it compile just fine :)

view this post on Zulip Anton (Oct 17 2023 at 13:44):

Hi @Daniel Haehre,
This indeed looks like a compiler bug and a strange one too, I'll file an issue.

view this post on Zulip Anton (Oct 17 2023 at 13:57):

There is a valuable tip in the error message:

 Any connection between types must use a named type variable, not
a *!

The tip could be further improved though.

Anyway, as a quick fix you can remove the type annotation getNum : Task Str *

view this post on Zulip Daniel Haehre (Oct 17 2023 at 13:58):

Ah. So that means it’s not a compiler bug?

view this post on Zulip Anton (Oct 17 2023 at 13:59):

I don't think so, but it confuses me too :p

view this post on Zulip Daniel Haehre (Oct 17 2023 at 14:02):

Hehe, that’s kinda nice I guess :sweat_smile:

view this post on Zulip Anton (Oct 17 2023 at 14:23):

In the end I do think this is a bug, I've simplified this to:

hello : Task {} *
hello =
    Stdout.line "Hello Alice"

hi : Task {} *
hi =
    Stdout.line "Hey Bob"

main =
    _ <- Task.await hello

    hi

Because you're stating the exact type of Stdout.line I believe we should make this work.

view this post on Zulip Anton (Oct 17 2023 at 14:30):

I wrote this up in #5912


Last updated: Jul 05 2025 at 12:14 UTC