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.
note: Might be cool to show what arguments the function got, in the error msg, to help diagnose
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.
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
^^^^
YESS thank you @Ghislain !
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:
ohhh
so what I should do if I want multiple Stdout.line
is:
_ <- Stdout.line "hello joe"
Stdout.line "hello"
thank you for clarifying!
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
You can use Task.await
to do that
Stdout.line "hello joe" |> Task.await \_ ->
Stdout.line "hello"
or with backpassing
_ <- Stdout.line "hello joe" |> Task.await
Stdout.line "hello"
oh yeah, Task.await is required! :thumbs_up:
Yes to "chain" your multiple Task
s
Last updated: Jul 06 2025 at 12:14 UTC