Skip to content

Repetition

Repetition is a common requirement when working with effects in software development. It allows us to perform an effect multiple times according to a specific repetition policy.

The Effect.repeat function returns a new effect that repeats the given effect according to a specified schedule or until the first failure.

Example (Repeating a Successful Effect)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Schedule
Schedule
,
import Console
Console
} from "effect"
// Define an effect that logs a message to the console
const
const action: Effect.Effect<void, never, never>
action
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("success")
// Define a schedule that repeats the action 2 more times with a delay
const
const policy: Schedule.Schedule<number, unknown, never>
policy
=
import Schedule
Schedule
.
const addDelay: <number, unknown, never>(self: Schedule.Schedule<number, unknown, never>, f: (out: number) => DurationInput) => Schedule.Schedule<number, unknown, never> (+1 overload)

Returns a new schedule with the given delay added to every interval defined by this schedule.

@since2.0.0

addDelay
(
import Schedule
Schedule
.
const recurs: (n: number) => Schedule.Schedule<number>

A schedule spanning all time, which can be stepped only the specified number of times before it terminates.

@since2.0.0

recurs
(2), () => "100 millis")
// Repeat the action according to the schedule
const
const program: Effect.Effect<number, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const repeat: <void, never, never, number, never>(self: Effect.Effect<void, never, never>, schedule: Schedule.Schedule<number, void, never>) => Effect.Effect<number, never, never> (+3 overloads)

The repeat function returns a new effect that repeats the given effect according to a specified schedule or until the first failure. The scheduled recurrences are in addition to the initial execution, so repeat(action, Schedule.once) executes action once initially, and if it succeeds, repeats it an additional time.

@example

// Success Example
import { Effect, Schedule, Console } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
const program = Effect.repeat(action, policy)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))

@example

// Failure Example import { Effect, Schedule } from "effect"

let count = 0

// Define an async effect that simulates an action with possible failures const action = Effect.async<string, string>((resume) => { if (count > 1) { console.log("failure") resume(Effect.fail("Uh oh!")) } else { count++ console.log("success") resume(Effect.succeed("yay!")) } })

const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis") const program = Effect.repeat(action, policy)

Effect.runPromiseExit(program).then(console.log)

@since2.0.0

repeat
(
const action: Effect.Effect<void, never, never>
action
,
const policy: Schedule.Schedule<number, unknown, never>
policy
)
// Run the program and log the number of repetitions
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <number, never>(effect: Effect.Effect<number, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<number>

Executes an effect and returns the result as a Promise.

When to Use

Use runPromise when you need to execute an effect and work with the result using Promise syntax, typically for compatibility with other promise-based code.

If the effect succeeds, the promise will resolve with the result. If the effect fails, the promise will reject with an error.

@seerunPromiseExit for a version that returns an Exit type instead of rejecting.

@example

// Title: Running a Successful Effect as a Promise
import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)
// Output: 1

@example

//Example: Handling a Failing Effect as a Rejected Promise import { Effect } from "effect"

Effect.runPromise(Effect.fail("my error")).catch(console.error) // Output: // (FiberFailure) Error: my error

@since2.0.0

runPromise
(
const program: Effect.Effect<number, never, never>
program
).
Promise<number>.then<void, never>(onfulfilled?: ((value: number) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
((
n: number
n
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
globalThis.Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`repetitions: ${
n: number
n
}`))
/*
Output:
success
success
success
repetitions: 2
*/

Example (Handling Failures in Repetition)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Schedule
Schedule
} from "effect"
let
let count: number
count
= 0
// Define an async effect that simulates an action with potential failure
const
const action: Effect.Effect<string, string, never>
action
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const async: <string, string, never>(resume: (callback: (_: Effect.Effect<string, string, never>) => void, signal: AbortSignal) => void | Effect.Effect<void, never, never>, blockingOn?: FiberId) => Effect.Effect<...>

Creates an Effect from a callback-based asynchronous function.

Details

The resume function:

  • Must be called exactly once. Any additional calls will be ignored.
  • Can return an optional Effect that will be run if the Fiber executing this Effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted.
  • Can receive an AbortSignal to handle interruption if needed.

The FiberId of the fiber that may complete the async callback may also be specified using the blockingOn argument. This is called the "blocking fiber" because it suspends the fiber executing the async effect (i.e. semantically blocks the fiber from making progress). Specifying this fiber id in cases where it is known will improve diagnostics, but not affect the behavior of the returned effect.

When to Use

Use Effect.async when dealing with APIs that use callback-style instead of async/await or Promise.

@example

// Title: Wrapping a Callback API
import { Effect } from "effect"
import * as NodeFS from "node:fs"
const readFile = (filename: string) =>
Effect.async<Buffer, Error>((resume) => {
NodeFS.readFile(filename, (error, data) => {
if (error) {
// Resume with a failed Effect if an error occurs
resume(Effect.fail(error))
} else {
// Resume with a succeeded Effect if successful
resume(Effect.succeed(data))
}
})
})
// ┌─── Effect<Buffer, Error, never>
// ▼
const program = readFile("example.txt")

@example

// Title: Handling Interruption with Cleanup import { Effect, Fiber } from "effect" import * as NodeFS from "node:fs"

// Simulates a long-running operation to write to a file const writeFileWithCleanup = (filename: string, data: string) => Effect.async<void, Error>((resume) => { const writeStream = NodeFS.createWriteStream(filename)

// Start writing data to the file
writeStream.write(data)
// When the stream is finished, resume with success
writeStream.on("finish", () => resume(Effect.void))
// In case of an error during writing, resume with failure
writeStream.on("error", (err) => resume(Effect.fail(err)))
// Handle interruption by returning a cleanup effect
return Effect.sync(() => {
console.log(`Cleaning up ${filename}`)
NodeFS.unlinkSync(filename)
})

})

const program = Effect.gen(function* () { const fiber = yield* Effect.fork( writeFileWithCleanup("example.txt", "Some long data...") ) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) // This will trigger the cleanup })

// Run the program Effect.runPromise(program) // Output: // Cleaning up example.txt

@example

// Title: Handling Interruption with AbortSignal import { Effect, Fiber } from "effect"

// A task that supports interruption using AbortSignal const interruptibleTask = Effect.async<void, Error>((resume, signal) => { // Handle interruption signal.addEventListener("abort", () => { console.log("Abort signal received") clearTimeout(timeoutId) })

// Simulate a long-running task const timeoutId = setTimeout(() => { console.log("Operation completed") resume(Effect.void) }, 2000) })

const program = Effect.gen(function* () { const fiber = yield* Effect.fork(interruptibleTask) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) })

// Run the program Effect.runPromise(program) // Output: // Abort signal received

@since2.0.0

async
<string, string>((
resume: (_: Effect.Effect<string, string, never>) => void
resume
) => {
if (
let count: number
count
> 1) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("failure")
resume: (_: Effect.Effect<string, string, never>) => void
resume
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <string>(error: string) => Effect.Effect<never, string, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
("Uh oh!"))
} else {
let count: number
count
++
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("success")
resume: (_: Effect.Effect<string, string, never>) => void
resume
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("yay!"))
}
})
// Define a schedule that repeats the action 2 more times with a delay
const
const policy: Schedule.Schedule<number, unknown, never>
policy
=
import Schedule
Schedule
.
const addDelay: <number, unknown, never>(self: Schedule.Schedule<number, unknown, never>, f: (out: number) => DurationInput) => Schedule.Schedule<number, unknown, never> (+1 overload)

Returns a new schedule with the given delay added to every interval defined by this schedule.

@since2.0.0

addDelay
(
import Schedule
Schedule
.
const recurs: (n: number) => Schedule.Schedule<number>

A schedule spanning all time, which can be stepped only the specified number of times before it terminates.

@since2.0.0

recurs
(2), () => "100 millis")
// Repeat the action according to the schedule
const
const program: Effect.Effect<number, string, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const repeat: <string, string, never, number, never>(self: Effect.Effect<string, string, never>, schedule: Schedule.Schedule<number, string, never>) => Effect.Effect<number, string, never> (+3 overloads)

The repeat function returns a new effect that repeats the given effect according to a specified schedule or until the first failure. The scheduled recurrences are in addition to the initial execution, so repeat(action, Schedule.once) executes action once initially, and if it succeeds, repeats it an additional time.

@example

// Success Example
import { Effect, Schedule, Console } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
const program = Effect.repeat(action, policy)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))

@example

// Failure Example import { Effect, Schedule } from "effect"

let count = 0

// Define an async effect that simulates an action with possible failures const action = Effect.async<string, string>((resume) => { if (count > 1) { console.log("failure") resume(Effect.fail("Uh oh!")) } else { count++ console.log("success") resume(Effect.succeed("yay!")) } })

const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis") const program = Effect.repeat(action, policy)

Effect.runPromiseExit(program).then(console.log)

@since2.0.0

repeat
(
const action: Effect.Effect<string, string, never>
action
,
const policy: Schedule.Schedule<number, unknown, never>
policy
)
// Run the program and observe the result on failure
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromiseExit: <number, string>(effect: Effect.Effect<number, string, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<Exit<number, string>>

Runs an effect and returns a Promise that resolves to an Exit, which represents the outcome (success or failure) of the effect.

When to Use

Use runPromiseExit when you need to determine if an effect succeeded or failed, including any defects, and you want to work with a Promise.

Details

The Exit type represents the result of the effect:

  • If the effect succeeds, the result is wrapped in a Success.
  • If it fails, the failure information is provided as a Failure containing a Cause type.

@example

// Title: Handling Results as Exit
import { Effect } from "effect"
// Execute a successful effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Success",
// value: 1
// }
// Execute a failing effect and get the Exit result as a Promise
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
// Output:
// {
// _id: "Exit",
// _tag: "Failure",
// cause: {
// _id: "Cause",
// _tag: "Fail",
// failure: "my error"
// }
// }

@since2.0.0

runPromiseExit
(
const program: Effect.Effect<number, string, never>
program
).
Promise<Exit<number, string>>.then<void, never>(onfulfilled?: ((value: Exit<number, string>) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
)
/*
Output:
success
success
failure
{
_id: 'Exit',
_tag: 'Failure',
cause: { _id: 'Cause', _tag: 'Fail', failure: 'Uh oh!' }
}
*/

If you want to avoid the first execution and only run the action according to a schedule, you can use Effect.schedule. This allows the effect to skip the initial run and follow the defined repeat policy.

Example (Skipping First Execution)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Schedule
Schedule
,
import Console
Console
} from "effect"
const
const action: Effect.Effect<void, never, never>
action
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("success")
const
const policy: Schedule.Schedule<number, unknown, never>
policy
=
import Schedule
Schedule
.
const addDelay: <number, unknown, never>(self: Schedule.Schedule<number, unknown, never>, f: (out: number) => DurationInput) => Schedule.Schedule<number, unknown, never> (+1 overload)

Returns a new schedule with the given delay added to every interval defined by this schedule.

@since2.0.0

addDelay
(
import Schedule
Schedule
.
const recurs: (n: number) => Schedule.Schedule<number>

A schedule spanning all time, which can be stepped only the specified number of times before it terminates.

@since2.0.0

recurs
(2), () => "100 millis")
const
const program: Effect.Effect<number, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const schedule: <void, never, never, never, number>(self: Effect.Effect<void, never, never>, schedule: Schedule.Schedule<number, unknown, never>) => Effect.Effect<number, never, never> (+1 overload)

Runs this effect according to the specified schedule.

See scheduleFrom for a variant that allows the schedule's decision to depend on the result of this effect.

@since2.0.0

schedule
(
const action: Effect.Effect<void, never, never>
action
,
const policy: Schedule.Schedule<number, unknown, never>
policy
)
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <number, never>(effect: Effect.Effect<number, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<number>

Executes an effect and returns the result as a Promise.

When to Use

Use runPromise when you need to execute an effect and work with the result using Promise syntax, typically for compatibility with other promise-based code.

If the effect succeeds, the promise will resolve with the result. If the effect fails, the promise will reject with an error.

@seerunPromiseExit for a version that returns an Exit type instead of rejecting.

@example

// Title: Running a Successful Effect as a Promise
import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)
// Output: 1

@example

//Example: Handling a Failing Effect as a Rejected Promise import { Effect } from "effect"

Effect.runPromise(Effect.fail("my error")).catch(console.error) // Output: // (FiberFailure) Error: my error

@since2.0.0

runPromise
(
const program: Effect.Effect<number, never, never>
program
).
Promise<number>.then<void, never>(onfulfilled?: ((value: number) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
((
n: number
n
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
globalThis.Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`repetitions: ${
n: number
n
}`))
/*
Output:
success
success
repetitions: 2
*/

The repeatN function returns a new effect that repeats the specified effect a given number of times or until the first failure. The repeats are in addition to the initial execution, so Effect.repeatN(action, 1) executes action once initially and then repeats it one additional time if it succeeds.

Example (Repeating an Action Multiple Times)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Console
Console
} from "effect"
const
const action: Effect.Effect<void, never, never>
action
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("success")
// Repeat the action 2 additional times after the first execution
const
const program: Effect.Effect<void, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const repeatN: <void, never, never>(self: Effect.Effect<void, never, never>, n: number) => Effect.Effect<void, never, never> (+1 overload)

The repeatN function returns a new effect that repeats the specified effect a given number of times or until the first failure. The repeats are in addition to the initial execution, so repeatN(action, 1) executes action once initially and then repeats it one additional time if it succeeds.

@example

import { Effect, Console } from "effect"
const action = Console.log("success")
const program = Effect.repeatN(action, 2)
Effect.runPromise(program)

@since2.0.0

repeatN
(
const action: Effect.Effect<void, never, never>
action
, 2)
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <void, never>(effect: Effect.Effect<void, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<void>

Executes an effect and returns the result as a Promise.

When to Use

Use runPromise when you need to execute an effect and work with the result using Promise syntax, typically for compatibility with other promise-based code.

If the effect succeeds, the promise will resolve with the result. If the effect fails, the promise will reject with an error.

@seerunPromiseExit for a version that returns an Exit type instead of rejecting.

@example

// Title: Running a Successful Effect as a Promise
import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)
// Output: 1

@example

//Example: Handling a Failing Effect as a Rejected Promise import { Effect } from "effect"

Effect.runPromise(Effect.fail("my error")).catch(console.error) // Output: // (FiberFailure) Error: my error

@since2.0.0

runPromise
(
const program: Effect.Effect<void, never, never>
program
)
/*
Output:
success
success
success
*/

The repeatOrElse function returns a new effect that repeats the specified effect according to the given schedule or until the first failure. When a failure occurs, the failure value and schedule output are passed to a specified handler. Scheduled recurrences are in addition to the initial execution, so Effect.repeat(action, Schedule.once) executes action once initially and then repeats it an additional time if it succeeds.

Example (Handling Failure During Repeats)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Schedule
Schedule
} from "effect"
let
let count: number
count
= 0
// Define an async effect that simulates an action with possible failures
const
const action: Effect.Effect<string, string, never>
action
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const async: <string, string, never>(resume: (callback: (_: Effect.Effect<string, string, never>) => void, signal: AbortSignal) => void | Effect.Effect<void, never, never>, blockingOn?: FiberId) => Effect.Effect<...>

Creates an Effect from a callback-based asynchronous function.

Details

The resume function:

  • Must be called exactly once. Any additional calls will be ignored.
  • Can return an optional Effect that will be run if the Fiber executing this Effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted.
  • Can receive an AbortSignal to handle interruption if needed.

The FiberId of the fiber that may complete the async callback may also be specified using the blockingOn argument. This is called the "blocking fiber" because it suspends the fiber executing the async effect (i.e. semantically blocks the fiber from making progress). Specifying this fiber id in cases where it is known will improve diagnostics, but not affect the behavior of the returned effect.

When to Use

Use Effect.async when dealing with APIs that use callback-style instead of async/await or Promise.

@example

// Title: Wrapping a Callback API
import { Effect } from "effect"
import * as NodeFS from "node:fs"
const readFile = (filename: string) =>
Effect.async<Buffer, Error>((resume) => {
NodeFS.readFile(filename, (error, data) => {
if (error) {
// Resume with a failed Effect if an error occurs
resume(Effect.fail(error))
} else {
// Resume with a succeeded Effect if successful
resume(Effect.succeed(data))
}
})
})
// ┌─── Effect<Buffer, Error, never>
// ▼
const program = readFile("example.txt")

@example

// Title: Handling Interruption with Cleanup import { Effect, Fiber } from "effect" import * as NodeFS from "node:fs"

// Simulates a long-running operation to write to a file const writeFileWithCleanup = (filename: string, data: string) => Effect.async<void, Error>((resume) => { const writeStream = NodeFS.createWriteStream(filename)

// Start writing data to the file
writeStream.write(data)
// When the stream is finished, resume with success
writeStream.on("finish", () => resume(Effect.void))
// In case of an error during writing, resume with failure
writeStream.on("error", (err) => resume(Effect.fail(err)))
// Handle interruption by returning a cleanup effect
return Effect.sync(() => {
console.log(`Cleaning up ${filename}`)
NodeFS.unlinkSync(filename)
})

})

const program = Effect.gen(function* () { const fiber = yield* Effect.fork( writeFileWithCleanup("example.txt", "Some long data...") ) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) // This will trigger the cleanup })

// Run the program Effect.runPromise(program) // Output: // Cleaning up example.txt

@example

// Title: Handling Interruption with AbortSignal import { Effect, Fiber } from "effect"

// A task that supports interruption using AbortSignal const interruptibleTask = Effect.async<void, Error>((resume, signal) => { // Handle interruption signal.addEventListener("abort", () => { console.log("Abort signal received") clearTimeout(timeoutId) })

// Simulate a long-running task const timeoutId = setTimeout(() => { console.log("Operation completed") resume(Effect.void) }, 2000) })

const program = Effect.gen(function* () { const fiber = yield* Effect.fork(interruptibleTask) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) })

// Run the program Effect.runPromise(program) // Output: // Abort signal received

@since2.0.0

async
<string, string>((
resume: (_: Effect.Effect<string, string, never>) => void
resume
) => {
if (
let count: number
count
> 1) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("failure")
resume: (_: Effect.Effect<string, string, never>) => void
resume
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fail: <string>(error: string) => Effect.Effect<never, string, never>

Creates an Effect that represents a recoverable error.

When to Use

Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like

catchAll

or

catchTag

.

@seesucceed to create an effect that represents a successful value.

@example

// Title: Creating a Failed Effect
import { Effect } from "effect"
// ┌─── Effect<never, Error, never>
// ▼
const failure = Effect.fail(
new Error("Operation failed due to network error")
)

@since2.0.0

fail
("Uh oh!"))
} else {
let count: number
count
++
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("success")
resume: (_: Effect.Effect<string, string, never>) => void
resume
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const succeed: <string>(value: string) => Effect.Effect<string, never, never>

Creates an Effect that always succeeds with a given value.

When to Use

Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies.

@seefail to create an effect that represents a failure.

@example

// Title: Creating a Successful Effect
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)

@since2.0.0

succeed
("yay!"))
}
})
// Define a schedule that repeats up to 2 times
// with a 100ms delay between attempts
const
const policy: Schedule.Schedule<number, unknown, never>
policy
=
import Schedule
Schedule
.
const addDelay: <number, unknown, never>(self: Schedule.Schedule<number, unknown, never>, f: (out: number) => DurationInput) => Schedule.Schedule<number, unknown, never> (+1 overload)

Returns a new schedule with the given delay added to every interval defined by this schedule.

@since2.0.0

addDelay
(
import Schedule
Schedule
.
const recurs: (n: number) => Schedule.Schedule<number>

A schedule spanning all time, which can be stepped only the specified number of times before it terminates.

@since2.0.0

recurs
(2), () => "100 millis")
// Provide a handler to run when failure occurs after the retries
const
const program: Effect.Effect<number, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const repeatOrElse: <string, string, never, never, number, never, never>(self: Effect.Effect<string, string, never>, schedule: Schedule.Schedule<number, string, never>, orElse: (error: string, option: Option<...>) => Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

The repeatOrElse function returns a new effect that repeats the specified effect according to the given schedule or until the first failure. When a failure occurs, the failure value and schedule output are passed to a specified handler. Scheduled recurrences are in addition to the initial execution, so repeat(action, Schedule.once) executes action once initially and then repeats it an additional time if it succeeds.

@example

import { Effect, Schedule } from "effect"
let count = 0
// Define an async effect that simulates an action with possible failures
const action = Effect.async<string, string>((resume) => {
if (count > 1) {
console.log("failure")
resume(Effect.fail("Uh oh!"))
} else {
count++
console.log("success")
resume(Effect.succeed("yay!"))
}
})
const policy = Schedule.addDelay(
Schedule.recurs(2), // Repeat for a maximum of 2 times
() => "100 millis" // Add a delay of 100 milliseconds between repetitions
)
const program = Effect.repeatOrElse(action, policy, () =>
Effect.sync(() => {
console.log("orElse")
return count - 1
})
)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))

@since2.0.0

repeatOrElse
(
const action: Effect.Effect<string, string, never>
action
,
const policy: Schedule.Schedule<number, unknown, never>
policy
, () =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const sync: <number>(thunk: LazyArg<number>) => Effect.Effect<number, never, never>

Creates an Effect that represents a synchronous side-effectful computation.

Details

The provided function (thunk) must not throw errors; if it does, the error will be treated as a "defect".

This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like

catchAllDefect

.

When to Use

Use this function when you are sure the operation will not fail.

@seetry_try for a version that can handle failures.

@example

// Title: Logging a Message
import { Effect } from "effect"
const log = (message: string) =>
Effect.sync(() => {
console.log(message) // side effect
})
// ┌─── Effect<void, never, never>
// ▼
const program = log("Hello, World!")

@since2.0.0

sync
(() => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("orElse")
return
let count: number
count
- 1
})
)
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <number, never>(effect: Effect.Effect<number, never, never>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<number>

Executes an effect and returns the result as a Promise.

When to Use

Use runPromise when you need to execute an effect and work with the result using Promise syntax, typically for compatibility with other promise-based code.

If the effect succeeds, the promise will resolve with the result. If the effect fails, the promise will reject with an error.

@seerunPromiseExit for a version that returns an Exit type instead of rejecting.

@example

// Title: Running a Successful Effect as a Promise
import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)
// Output: 1

@example

//Example: Handling a Failing Effect as a Rejected Promise import { Effect } from "effect"

Effect.runPromise(Effect.fail("my error")).catch(console.error) // Output: // (FiberFailure) Error: my error

@since2.0.0

runPromise
(
const program: Effect.Effect<number, never, never>
program
).
Promise<number>.then<void, never>(onfulfilled?: ((value: number) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
((
n: number
n
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`repetitions: ${
n: number
n
}`))
/*
Output:
success
success
failure
orElse
repetitions: 1
*/

You can control the repetition of an effect by a condition using either a while or until option, allowing for dynamic control based on runtime outcomes.

Example (Repeating Until a Condition is Met)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect"
let
let count: number
count
= 0
// Define an effect that simulates varying outcomes on each invocation
const
const action: Effect.Effect<number, never, never>
action
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const sync: <number>(thunk: LazyArg<number>) => Effect.Effect<number, never, never>

Creates an Effect that represents a synchronous side-effectful computation.

Details

The provided function (thunk) must not throw errors; if it does, the error will be treated as a "defect".

This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like

catchAllDefect

.

When to Use

Use this function when you are sure the operation will not fail.

@seetry_try for a version that can handle failures.

@example

// Title: Logging a Message
import { Effect } from "effect"
const log = (message: string) =>
Effect.sync(() => {
console.log(message) // side effect
})
// ┌─── Effect<void, never, never>
// ▼
const program = log("Hello, World!")

@since2.0.0

sync
(() => {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`Action called ${++
let count: number
count
} time(s)`)
return
let count: number
count
})
// Repeat the action until the count reaches 3
const
const program: Effect.Effect<3, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const repeat: <number, never, never, {
until: (n: number) => n is 3;
}>(self: Effect.Effect<number, never, never>, options: {
until: (n: number) => n is 3;
}) => Effect.Effect<3, never, never> (+3 overloads)

The repeat function returns a new effect that repeats the given effect according to a specified schedule or until the first failure. The scheduled recurrences are in addition to the initial execution, so repeat(action, Schedule.once) executes action once initially, and if it succeeds, repeats it an additional time.

@example

// Success Example
import { Effect, Schedule, Console } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
const program = Effect.repeat(action, policy)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))

@example

// Failure Example import { Effect, Schedule } from "effect"

let count = 0

// Define an async effect that simulates an action with possible failures const action = Effect.async<string, string>((resume) => { if (count > 1) { console.log("failure") resume(Effect.fail("Uh oh!")) } else { count++ console.log("success") resume(Effect.succeed("yay!")) } })

const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis") const program = Effect.repeat(action, policy)

Effect.runPromiseExit(program).then(console.log)

@since2.0.0

repeat
(
const action: Effect.Effect<number, never, never>
action
, {
until: (n: number) => n is 3
until
: (
n: number
n
) =>
n: number
n
=== 3 })
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <3, never>(effect: Effect.Effect<3, never, never>, options?: RunForkOptions) => RuntimeFiber<3, never>

The foundational function for running effects, returning a "fiber" that can be observed or interrupted.

When to Use

runFork is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

@example

// Title: Running an Effect in the Background
import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: Effect.Effect<3, never, never>
program
)
/*
Output:
Action called 1 time(s)
Action called 2 time(s)
Action called 3 time(s)
*/