diff --git a/examples/interactive/cli-platform/Program.roc b/examples/interactive/cli-platform/Program.roc index 82a16d008b..fd837b226c 100644 --- a/examples/interactive/cli-platform/Program.roc +++ b/examples/interactive/cli-platform/Program.roc @@ -1,10 +1,34 @@ interface Program - exposes [Program, noArgs, withArgs, quick, withEnv] + exposes [Program, ExitCode, noArgs, withArgs, quick, withEnv, exitCode, exit] imports [Task.{ Task }, InternalProgram.{ InternalProgram }, InternalTask, Effect] ## A [command-line interface](https://en.wikipedia.org/wiki/Command-line_interface) program. Program : InternalProgram +## An [exit status](https://en.wikipedia.org/wiki/Exit_status) code. +ExitCode := U8 + +## Converts a [U8] to an [ExitCode]. +## +## If you already have a [Task] and want to convert its success type +## from `{}` to [ExitCode], you may find [Program.exit] convenient. +exitCode : U8 -> ExitCode +exitCode = @ExitCode + +## Attach an [ExitCode] to a task. +## +## Stderr.line "I hit an error and couldn't continue." +## |> Program.exit 1 +## +## Note that this does not terminate the current process! By design, this platform does not have +## a [Task] which terminates the current process. Instead, error handling should be consistently +## done through task failures. +## +## To convert a [U8] directly into an [ExitCode], use [Program.exitCode]. +exit : Task {} [] fx, U8 -> Task ExitCode [] fx +exit = \task, code -> + Task.map task \{} -> @ExitCode code + ## A program which runs the given task and discards the values it produces on success or failure. ## One use for this is as an introductory [Program] when teaching someone how to use this platform. ## @@ -31,13 +55,13 @@ quick = \task -> ## the task's potential failures using something like [Task.attempt]. ## ## For a similar program which does use command-line arguments, see [Program.withArgs]. -noArgs : Task U8 [] * -> Program +noArgs : Task ExitCode [] * -> Program noArgs = \task -> effect = InternalTask.toEffect task |> Effect.map \result -> when result is - Ok exitStatus -> exitStatus + Ok (@ExitCode u8) -> u8 Err _ -> 0 # TODO this is unreachable! Remove it after https://github.com/roc-lang/roc/issues/4054 lands InternalProgram.fromEffect effect @@ -51,14 +75,14 @@ noArgs = \task -> ## If any command-line arguments contain invalid Unicode, the invalid parts will be replaced with ## the [Unicode replacement character](https://unicode.org/glossary/#replacement_character) ## (`�`). -withArgs : (List Str -> Task U8 [] *) -> Program +withArgs : (List Str -> Task ExitCode [] *) -> Program withArgs = \toTask -> effect = Effect.after Effect.args \args -> toTask args |> InternalTask.toEffect |> Effect.map \result -> when result is - Ok exitStatus -> exitStatus + Ok (@ExitCode u8) -> u8 Err _ -> 0 # TODO this is unreachable! Remove it after https://github.com/roc-lang/roc/issues/4054 lands InternalProgram.fromEffect effect @@ -66,14 +90,14 @@ withArgs = \toTask -> ## A program which uses [command-line arguments](https://en.wikipedia.org/wiki/Command-line_interface#Arguments) ## and a dictionary of [environment variables](https://en.wikipedia.org/wiki/Environment_variable). ## -## This is a combination of [Program.withArgs] and [Env.dict]. Note that the task's failure type +## This is a combination of [Program.withArgs] and `Env.dict`. Note that the task's failure type ## must be `[]`. You can satisfy that by handling all the task's potential failures using ## something like [Task.attempt]. ## ## If any command-line arguments contain invalid Unicode, the invalid parts will be replaced with ## the [Unicode replacement character](https://unicode.org/glossary/#replacement_character) ## (`�`). -withEnv : (List Str, Dict Str Str -> Task U8 [] *) -> Program +withEnv : (List Str, Dict Str Str -> Task ExitCode [] *) -> Program withEnv = \toTask -> effect = args <- Effect.args |> Effect.after @@ -83,7 +107,7 @@ withEnv = \toTask -> |> InternalTask.toEffect |> Effect.map \result -> when result is - Ok exitStatus -> exitStatus + Ok (@ExitCode code) -> code Err _ -> 0 # TODO this is unreachable! Remove it after https://github.com/roc-lang/roc/issues/4054 lands InternalProgram.fromEffect effect diff --git a/examples/interactive/file.roc b/examples/interactive/file.roc index 799fd65104..79dfde87f7 100644 --- a/examples/interactive/file.roc +++ b/examples/interactive/file.roc @@ -1,7 +1,7 @@ app "file-io" packages { pf: "cli-platform/main.roc" } imports [ - pf.Program.{ Program }, + pf.Program.{ Program, ExitCode }, pf.Stdout, pf.Stderr, pf.Task.{ Task }, @@ -15,7 +15,7 @@ app "file-io" main : Program main = Program.noArgs mainTask -mainTask : Task U8 [] [Write [File, Stdout, Stderr], Read [File], Env] +mainTask : Task ExitCode [] [Write [File, Stdout, Stderr], Read [File], Env] mainTask = path = Path.fromStr "out.txt" task = @@ -36,7 +36,7 @@ mainTask = when result is Ok {} -> Stdout.line "Successfully wrote a string to out.txt" - |> Task.map \{} -> 0 # exit status + |> Program.exit 0 Err err -> msg = @@ -48,4 +48,4 @@ mainTask = _ -> "Uh oh, there was an error!" Stderr.line msg - |> Task.map \{} -> 1 # exit status \ No newline at end of file + |> Program.exit 1 \ No newline at end of file