Stream: beginners

Topic: Stdout.line getting 3 args somehow


view this post on Zulip Juliano (Dec 03 2022 at 14:23):

The error:

The line function expects 1 argument, but it got 3 instead:

23│          |> Stdout.line
                ^^^^^^^^^^^

The code:

app "day1"
    packages { pf: "basic-cli/src/main.roc" }
    imports [pf.Stdout, pf.File, pf.Task, pf.Path, Json]
    provides [main] to pf

main =
    content <- "./aoc22/day1.txt"
        |> Path.fromStr
        |> File.readUtf8
        |> Task.onFail (\err ->
            when err is
                FileReadUtf8Err _path _fileErr -> crash "FileReadUtf8Err"
                FileReadErr _ _ -> crash "FileReadErr: asd"
        )
        |> Task.await

    split = content
        |> Str.split "\n"
    split
        |> Encode.toBytes Json.toUtf8
        |> Str.fromUtf8
        |> Result.withDefault "err"
        |> Stdout.line
    Stdout.line "hi"

I tried taking putting Stdout.line out of the pipeline:

str = split
    |> Encode.toBytes Json.toUtf8
    |> Str.fromUtf8
    |> Result.withDefault "err"
Stdout.line str

The same error happens on the Stdout.line str line.

view this post on Zulip Juliano (Dec 03 2022 at 14:25):

note: Might be cool to show what arguments the function got, in the error msg, to help diagnose

view this post on Zulip Ghislain (Dec 03 2022 at 14:35):

It looks like a bug from the compiler misinterpreting the indentation of your Stdout.line "hi".
It's thinking your |> Stdout.line takes 3 arguments :
1 - the result of |> Result.withDefault "err"
2 - Stdout.line
3 - "hi"
It should be ok if you remove you last line.

view this post on Zulip Juliano (Dec 03 2022 at 14:37):

To try to get a diff, I thought "i'll define a 3-arg function with the wrong types and roc will show the diff to me"

app "day1"
    packages { pf: "basic-cli/src/main.roc" }
    imports [pf.Stdout, pf.File, pf.Task, pf.Path, Json]
    provides [main] to pf

help : Str, Str, Str -> Str
help = \a,b,c -> c

main =
    content <- "./aoc22/day1.txt"
        |> Path.fromStr
        |> File.readUtf8
        |> Task.onFail (\err ->
            when err is
                FileReadUtf8Err _path _fileErr -> crash "FileReadUtf8Err"
                FileReadErr _ _ -> crash "FileReadErr: asd"
        )
        |> Task.await

    split = content
        |> Str.split "\n"
    a = split
        |> Encode.toBytes Json.toUtf8
        |> Str.fromUtf8
        |> Result.withDefault "err"
        |> help

    Stdout.line "hi"

But now it says there's a single argument

The help function expects 3 arguments, but it got only 1:

26          |> help
                ^^^^

view this post on Zulip Juliano (Dec 03 2022 at 14:38):

YESS thank you @Ghislain !

view this post on Zulip Ghislain (Dec 03 2022 at 15:17):

To understand the difference with your last example, you changed something important:

split # no new definition, so it has to be the returned value
   |> Encode.toBytes Json.toUtf8
   |> Str.fromUtf8
   |> Result.withDefault "err"
   |> Stdout.line

Stdout.line "hi" # compiler understands that the previous expression is not finished yet because it had to be the last and returned value
a = split # definition of 'a' => it can't be the last expression
   |> ...
   |> help

Stdout.line "hi" # <- no new definition, so it has to be the returned value

Hope it's clearer :sweat_smile:

view this post on Zulip Juliano (Dec 03 2022 at 15:29):

ohhh

view this post on Zulip Juliano (Dec 03 2022 at 15:30):

so what I should do if I want multiple Stdout.line is:

_ <- Stdout.line "hello joe"
Stdout.line "hello"

view this post on Zulip Juliano (Dec 03 2022 at 15:30):

thank you for clarifying!

view this post on Zulip Ghislain (Dec 03 2022 at 15:31):

ah, no, you can't do that because it would mean:

Stdout.line "hello joe" \_ ->
    Stdout.line "hello"

But Stdout.line doesn't take 2 arguments

view this post on Zulip Ghislain (Dec 03 2022 at 15:34):

You can use Task.await to do that

view this post on Zulip Ghislain (Dec 03 2022 at 15:35):

Stdout.line "hello joe" |> Task.await \_ ->
    Stdout.line "hello"

or with backpassing

_ <- Stdout.line "hello joe" |> Task.await
Stdout.line "hello"

view this post on Zulip Juliano (Dec 03 2022 at 15:37):

oh yeah, Task.await is required! :thumbs_up:

view this post on Zulip Ghislain (Dec 03 2022 at 15:39):

Yes to "chain" your multiple Tasks


Last updated: Jul 06 2025 at 12:14 UTC