Loop Effects
Sometimes, you need to repeat an effectful function, multiple times until a particular event occurs. In roc, you can use a recursive function to do this.
We'll demonstrate this by adding numbers read from stdin until the end of input (Ctrl-D or end of file).
Full Code
app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.18.0/0APbwVN1_p1mJ96tXjaoiUCr8NBGamr8G8Ac_DrXR-o.tar.br", } import pf.Stdin import pf.Stdout import pf.Stderr main! = \_args -> when run! {} is Ok {} -> Ok {} Err err -> print_err! err run! : {} => Result {} _ run! = \_ -> try Stdout.line! "Enter some numbers on different lines, then press Ctrl-D to sum them up." sum = try add_number_from_stdin! 0 Stdout.line! "Sum: $(Num.toStr sum)" add_number_from_stdin! : I64 => Result I64 _ add_number_from_stdin! = \sum -> when Stdin.line! {} is Ok input -> when Str.toI64 input is Ok num -> add_number_from_stdin! (sum + num) Err _ -> Err (NotNum input) Err EndOfFile -> Ok sum Err err -> err |> Inspect.toStr |> NotNum |> Err print_err! : _ => Result {} _ print_err! = \err -> when err is NotNum text -> Stderr.line! "Error: \"$(text)\" is not a valid I64 number." _ -> Stderr.line! "Error: $(Inspect.toStr err)"
Output
Run this from the directory that has main.roc
in it:
$ roc main.roc < numbers.txt Enter some numbers on different lines, then press Ctrl-D to sum them up. Sum: 178