Terminal
On this page
The @effect/platform/Terminal
module provides an abstraction for interacting with standard input and output, including reading user input and displaying messages on the terminal.
Basic Usage
The module provides a single Terminal
tag, which serves as the entry point to reading from and writing to standard input and standard output.
ts
import {Terminal } from "@effect/platform"import {Effect } from "effect"constprogram =Effect .gen (function* () {constterminal = yield*Terminal .Terminal // use `terminal` to interact with standard input and output})
ts
import {Terminal } from "@effect/platform"import {Effect } from "effect"constprogram =Effect .gen (function* () {constterminal = yield*Terminal .Terminal // use `terminal` to interact with standard input and output})
Writing to standard output
ts
import {Terminal } from "@effect/platform"import {NodeRuntime ,NodeTerminal } from "@effect/platform-node"import {Effect } from "effect"constprogram =Effect .gen (function* () {constterminal = yield*Terminal .Terminal yield*terminal .display ("a message\n")})NodeRuntime .runMain (program .pipe (Effect .provide (NodeTerminal .layer )))// Output: "a message"
ts
import {Terminal } from "@effect/platform"import {NodeRuntime ,NodeTerminal } from "@effect/platform-node"import {Effect } from "effect"constprogram =Effect .gen (function* () {constterminal = yield*Terminal .Terminal yield*terminal .display ("a message\n")})NodeRuntime .runMain (program .pipe (Effect .provide (NodeTerminal .layer )))// Output: "a message"
Reading from standard input
ts
import {Terminal } from "@effect/platform"import {NodeRuntime ,NodeTerminal } from "@effect/platform-node"import {Effect } from "effect"constprogram =Effect .gen (function* () {constterminal = yield*Terminal .Terminal constinput = yield*terminal .readLine console .log (`input: ${input }`)})NodeRuntime .runMain (program .pipe (Effect .provide (NodeTerminal .layer )))// Input: "hello"// Output: "input: hello"
ts
import {Terminal } from "@effect/platform"import {NodeRuntime ,NodeTerminal } from "@effect/platform-node"import {Effect } from "effect"constprogram =Effect .gen (function* () {constterminal = yield*Terminal .Terminal constinput = yield*terminal .readLine console .log (`input: ${input }`)})NodeRuntime .runMain (program .pipe (Effect .provide (NodeTerminal .layer )))// Input: "hello"// Output: "input: hello"
Example: Number guessing game
This example demonstrates how to create a complete number-guessing game by reading input from the terminal and providing feedback to the user. The game continues until the user guesses the correct number.
ts
import {Terminal } from "@effect/platform"import type {PlatformError } from "@effect/platform/Error"import {Effect ,Option ,Random } from "effect"import {NodeRuntime ,NodeTerminal } from "@effect/platform-node"constsecret =Random .nextIntBetween (1, 100)constparseGuess = (input : string) => {constn =parseInt (input , 10)returnisNaN (n ) ||n < 1 ||n > 100 ?Option .none () :Option .some (n )}constdisplay = (message : string) =>Effect .gen (function* () {constterminal = yield*Terminal .Terminal yield*terminal .display (`${message }\n`)})constprompt =Effect .gen (function* () {constterminal = yield*Terminal .Terminal yield*terminal .display ("Enter a guess: ")return yield*terminal .readLine })constanswer :Effect .Effect <number,Terminal .QuitException |PlatformError ,Terminal .Terminal > =Effect .gen (function* () {constinput = yield*prompt constguess =parseGuess (input )if (Option .isNone (guess )) {yield*display ("You must enter an integer from 1 to 100")return yield*answer }returnguess .value })constcheck = <A ,E ,R >(secret : number,guess : number,ok :Effect .Effect <A ,E ,R >,ko :Effect .Effect <A ,E ,R >) =>Effect .gen (function* () {if (guess >secret ) {yield*display ("Too high")return yield*ko } else if (guess <secret ) {yield*display ("Too low")return yield*ko } else {return yield*ok }})constend =display ("You guessed it!")constloop = (secret : number):Effect .Effect <void,Terminal .QuitException |PlatformError ,Terminal .Terminal > =>Effect .gen (function* () {constguess = yield*answer return yield*check (secret ,guess ,end ,Effect .suspend (() =>loop (secret )))})constgame =Effect .gen (function* () {yield*display (`We have selected a random number between 1 and 100.See if you can guess it in 10 turns or fewer.We'll tell you if your guess was too high or too low.`)yield*loop (yield*secret )})NodeRuntime .runMain (game .pipe (Effect .provide (NodeTerminal .layer )))
ts
import {Terminal } from "@effect/platform"import type {PlatformError } from "@effect/platform/Error"import {Effect ,Option ,Random } from "effect"import {NodeRuntime ,NodeTerminal } from "@effect/platform-node"constsecret =Random .nextIntBetween (1, 100)constparseGuess = (input : string) => {constn =parseInt (input , 10)returnisNaN (n ) ||n < 1 ||n > 100 ?Option .none () :Option .some (n )}constdisplay = (message : string) =>Effect .gen (function* () {constterminal = yield*Terminal .Terminal yield*terminal .display (`${message }\n`)})constprompt =Effect .gen (function* () {constterminal = yield*Terminal .Terminal yield*terminal .display ("Enter a guess: ")return yield*terminal .readLine })constanswer :Effect .Effect <number,Terminal .QuitException |PlatformError ,Terminal .Terminal > =Effect .gen (function* () {constinput = yield*prompt constguess =parseGuess (input )if (Option .isNone (guess )) {yield*display ("You must enter an integer from 1 to 100")return yield*answer }returnguess .value })constcheck = <A ,E ,R >(secret : number,guess : number,ok :Effect .Effect <A ,E ,R >,ko :Effect .Effect <A ,E ,R >) =>Effect .gen (function* () {if (guess >secret ) {yield*display ("Too high")return yield*ko } else if (guess <secret ) {yield*display ("Too low")return yield*ko } else {return yield*ok }})constend =display ("You guessed it!")constloop = (secret : number):Effect .Effect <void,Terminal .QuitException |PlatformError ,Terminal .Terminal > =>Effect .gen (function* () {constguess = yield*answer return yield*check (secret ,guess ,end ,Effect .suspend (() =>loop (secret )))})constgame =Effect .gen (function* () {yield*display (`We have selected a random number between 1 and 100.See if you can guess it in 10 turns or fewer.We'll tell you if your guess was too high or too low.`)yield*loop (yield*secret )})NodeRuntime .runMain (game .pipe (Effect .provide (NodeTerminal .layer )))