Effect.ts
Effect.ts overview
Section titled “Effect.ts overview”Describes workflows that run only when executed by the Effect runtime.
An Effect<A, E, R> can succeed with an A, fail with an E, and require
services R. Creating an effect does not perform the work; it builds a value
that can be composed, provided with services, retried, interrupted, run
concurrently, or inspected by the runtime. This module is the main API for
creating effects, combining them, handling failures, managing resources, and
running effect programs.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- caching
- clock
- collecting
- condition checking
- conditional operators
- constructors
- context
- converting
- converting failures to defects
- delays & timeouts
- do notation
- eager
- effectify
- environment
- error accumulation
- error handling
- fallback
- filtering
- functions
- guards
- interruption
- logging
- mapping
- models
- outcome encapsulation
- pattern matching
- racing
- references
- repetition
- requests & batching
- resource management
- running
- sequencing
- supervision & fibers
- tracing
- tracking
- transactions
- type IDs
- type lambdas
- utility types
- utils
- zipping
caching
Section titled “caching”cached
Section titled “cached”Returns an effect that lazily computes a result and caches it for subsequent evaluations.
When to use
Use when you need an expensive or time-consuming operation to be evaluated once and reused by later callers.
Details
This function wraps an effect and ensures that its result is computed only once. Once the result is computed, it is cached, meaning that subsequent evaluations of the same effect will return the cached result without re-executing the logic.
Example (Memoizing an effect until invalidated)
import { Console, Effect } from "effect"
let i = 1const expensiveTask = Effect.promise<string>(() => { console.log("expensive task...") return new Promise((resolve) => { setTimeout(() => { resolve(`result ${i++}`) }, 100) })})
const program = Effect.gen(function* () { console.log("non-cached version:") yield* expensiveTask.pipe(Effect.andThen(Console.log)) yield* expensiveTask.pipe(Effect.andThen(Console.log)) console.log("cached version:") const cached = yield* Effect.cached(expensiveTask) yield* cached.pipe(Effect.andThen(Console.log)) yield* cached.pipe(Effect.andThen(Console.log))})
Effect.runFork(program)// Output:// non-cached version:// expensive task...// result 1// expensive task...// result 2// cached version:// expensive task...// result 3// result 3See
cachedWithTTLfor a similar function that includes a time-to-live duration for the cached value.cachedInvalidateWithTTLfor a similar function that includes an additional effect for manually invalidating the cached value.
Signature
declare const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>Since v2.0.0
cachedInvalidateWithTTL
Section titled “cachedInvalidateWithTTL”Creates a cached effect result for a specified duration and allows manual invalidation before expiration.
When to use
Use when an effect result should be cached for a bounded time and callers also need a manual invalidation effect to force recomputation before expiration.
Details
This function behaves similarly to cachedWithTTL by caching the
result of an effect for a specified period of time. However, it introduces an
additional feature: it provides an effect that allows you to manually
invalidate the cached result before it naturally expires.
This gives you more control over the cache, allowing you to refresh the result when needed, even if the original cache has not yet expired.
Once the cache is invalidated, the next time the effect is evaluated, the result will be recomputed, and the cache will be refreshed.
Example (Memoizing with TTL and invalidation)
import { Console, Effect } from "effect"
let i = 1const expensiveTask = Effect.promise<string>(() => { console.log("expensive task...") return new Promise((resolve) => { setTimeout(() => { resolve(`result ${i++}`) }, 100) })})
const program = Effect.gen(function* () { const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(expensiveTask, "1 hour") yield* cached.pipe(Effect.andThen(Console.log)) yield* cached.pipe(Effect.andThen(Console.log)) yield* invalidate yield* cached.pipe(Effect.andThen(Console.log))})
Effect.runFork(program)// Output:// expensive task...// result 1// result 1// expensive task...// result 2See
cachedfor a similar function that caches the result indefinitely.cachedWithTTLfor a similar function that caches the result for a specified duration but does not include an effect for manual invalidation.
Signature
declare const cachedInvalidateWithTTL: { (timeToLive: Duration.Input): <A, E, R>(self: Effect<A, E, R>) => Effect<[Effect<A, E, R>, Effect<void>]> <A, E, R>(self: Effect<A, E, R>, timeToLive: Duration.Input): Effect<[Effect<A, E, R>, Effect<void>]>}Since v2.0.0
cachedWithTTL
Section titled “cachedWithTTL”Returns an effect that caches its result for a specified Duration,
known as “timeToLive” (TTL).
When to use
Use when you need a costly effect result to be reused for a bounded duration before being recomputed.
Details
This function is used to cache the result of an effect for a specified amount of time. This means that the first time the effect is evaluated, its result is computed and stored.
If the effect is evaluated again within the specified timeToLive, the
cached result will be used, avoiding recomputation.
After the specified duration has passed, the cache expires, and the effect will be recomputed upon the next evaluation.
Example (Memoizing an effect with TTL)
import { Console, Effect } from "effect"
let i = 1const expensiveTask = Effect.promise<string>(() => { console.log("expensive task...") return new Promise((resolve) => { setTimeout(() => { resolve(`result ${i++}`) }, 100) })})
const program = Effect.gen(function* () { const cached = yield* Effect.cachedWithTTL(expensiveTask, "150 millis") yield* cached.pipe(Effect.andThen(Console.log)) yield* cached.pipe(Effect.andThen(Console.log)) yield* Effect.sleep("100 millis") yield* cached.pipe(Effect.andThen(Console.log))})
Effect.runFork(program)// Output:// expensive task...// result 1// result 1// expensive task...// result 2See
cachedfor a similar function that caches the result indefinitely.cachedInvalidateWithTTLfor a similar function that includes an additional effect for manually invalidating the cached value.
Signature
declare const cachedWithTTL: { (timeToLive: Duration.Input): <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>> <A, E, R>(self: Effect<A, E, R>, timeToLive: Duration.Input): Effect<Effect<A, E, R>>}Since v2.0.0
clockWith
Section titled “clockWith”Retrieves the Clock service from the context and provides it to the
specified effectful function.
Example (Accessing the Clock service)
import { Console, Effect } from "effect"
const program = Effect.clockWith((clock) => clock.currentTimeMillis.pipe( Effect.map((currentTime) => `Current time is: ${currentTime}`), Effect.tap(Console.log) ))
Effect.runFork(program)// Example Output:// Current time is: 1735484929744Signature
declare const clockWith: <A, E, R>(f: (clock: Clock) => Effect<A, E, R>) => Effect<A, E, R>Since v2.0.0
collecting
Section titled “collecting”Combines an iterable or record of effects into one effect whose success shape follows the input.
When to use
Use to run a known collection of effects and collect results in the same tuple, iterable, or record shape.
Details
Tuple and iterable inputs collect results in order. Record inputs collect results under the same keys. By default, the combined effect fails on the first failure; with concurrent execution, effects that have already started may be interrupted, while effects not yet started are skipped.
Options:
Use concurrency to control sequential or concurrent execution. Use
mode: "result" to run every effect and collect each success or failure as a
Result in the same output shape. Use discard: true to ignore successful
values and return void.
Example (Collecting tuple results in order)
import { Console, Effect } from "effect"
const tupleOfEffects = [ Effect.succeed(42).pipe(Effect.tap(Console.log)), Effect.succeed("Hello").pipe(Effect.tap(Console.log))] as const
// ┌─── Effect<[number, string], never, never>// ▼const resultsAsTuple = Effect.all(tupleOfEffects)
Effect.runPromise(resultsAsTuple).then(console.log)// Output:// 42// Hello// [ 42, 'Hello' ]Example (Collecting iterable results in order)
import { Console, Effect } from "effect"
const iterableOfEffects: Iterable<Effect.Effect<number>> = [1, 2, 3].map((n) => Effect.succeed(n).pipe(Effect.tap(Console.log)))
// ┌─── Effect<number[], never, never>// ▼const resultsAsArray = Effect.all(iterableOfEffects)
Effect.runPromise(resultsAsArray).then(console.log)// Output:// 1// 2// 3// [ 1, 2, 3 ]Example (Collecting struct results by key)
import { Console, Effect } from "effect"
const structOfEffects = { a: Effect.succeed(42).pipe(Effect.tap(Console.log)), b: Effect.succeed("Hello").pipe(Effect.tap(Console.log))}
// ┌─── Effect<{ a: number; b: string; }, never, never>// ▼const resultsAsStruct = Effect.all(structOfEffects)
Effect.runPromise(resultsAsStruct).then(console.log)// Output:// 42// Hello// { a: 42, b: 'Hello' }Example (Collecting record results by key)
import { Console, Effect } from "effect"
const recordOfEffects: Record<string, Effect.Effect<number>> = { key1: Effect.succeed(1).pipe(Effect.tap(Console.log)), key2: Effect.succeed(2).pipe(Effect.tap(Console.log))}
// ┌─── Effect<{ [x: string]: number; }, never, never>// ▼const resultsAsRecord = Effect.all(recordOfEffects)
Effect.runPromise(resultsAsRecord).then(console.log)// Output:// 1// 2// { key1: 1, key2: 2 }Example (Stopping on the first failure)
import { Console, Effect } from "effect"
const program = Effect.all([ Effect.succeed("Task1").pipe(Effect.tap(Console.log)), Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)), // Won't execute due to earlier failure Effect.succeed("Task3").pipe(Effect.tap(Console.log))])
Effect.runPromiseExit(program).then(console.log)// Output:// Task1// {// _id: 'Exit',// _tag: 'Failure',// cause: { _id: 'Cause', _tag: 'Fail', failure: 'Task2: Oh no!' }// }See
forEachfor iterating over elements and applying an effect.
Signature
declare const all: < const Arg extends Iterable<Effect<any, any, any>> | Record<string, Effect<any, any, any>>, O extends { readonly concurrency?: Concurrency | undefined readonly discard?: boolean | undefined readonly mode?: "default" | "result" | undefined }>( arg: Arg, options?: O) => All.Return<Arg, O>Since v2.0.0
findFirst
Section titled “findFirst”Returns the first element that satisfies an effectful predicate.
Details
The predicate receives the element and its index. Evaluation short-circuits as soon as an element matches.
Example (Finding the first successful match)
import { Effect } from "effect"
const program = Effect.findFirst([1, 2, 3, 4], (n) => Effect.succeed(n > 2))
Effect.runPromise(program).then(console.log)// { _id: 'Option', _tag: 'Some', value: 3 }Signature
declare const findFirst: { <A, E, R>( predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R> ): (elements: Iterable<A>) => Effect<Option<A>, E, R> <A, E, R>( elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R> ): Effect<Option<A>, E, R>}Since v2.0.0
findFirstFilter
Section titled “findFirstFilter”Returns the first value that passes an effectful FilterEffect.
When to use
Use when you need to find the first element that satisfies an effectful
filter returning a Result, which also transforms the matching element.
Details
The filter receives the element and index. Evaluation short-circuits on the
first Result.succeed and returns the transformed value in Option.some.
See
findFirstfor the simpler effectful predicate-based variant
Signature
declare const findFirstFilter: { <A, B, X, E, R>( filter: (input: NoInfer<A>, i: number) => Effect<Result.Result<B, X>, E, R> ): (elements: Iterable<A>) => Effect<Option<B>, E, R> <A, B, X, E, R>( elements: Iterable<A>, filter: (input: NoInfer<A>, i: number) => Effect<Result.Result<B, X>, E, R> ): Effect<Option<B>, E, R>}Since v4.0.0
forEach
Section titled “forEach”Executes an effectful operation for each element in an Iterable.
When to use
Use to traverse an iterable with an effectful function while preserving element order in the collected results.
Details
The forEach function applies a provided operation to each element in the
iterable, producing a new effect that returns an array of results.
If any effect fails, the iteration stops immediately (short-circuiting), and the error is propagated.
Concurrency:
The concurrency option controls how many operations are performed
concurrently. By default, the operations are performed sequentially.
Discarding Results:
If the discard option is set to true, the intermediate results are not
collected, and the final result of the operation is void.
Example (Mapping over an iterable with effects)
import { Console, Effect } from "effect"
const result = Effect.forEach([1, 2, 3, 4, 5], (n, index) => Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)))
Effect.runPromise(result).then(console.log)// Output:// Currently at index 0// Currently at index 1// Currently at index 2// Currently at index 3// Currently at index 4// [ 2, 4, 6, 8, 10 ]Example (Running effects without collecting results)
import { Console, Effect } from "effect"
// Apply effects but discard the resultsconst result = Effect.forEach( [1, 2, 3, 4, 5], (n, index) => Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)), { discard: true })
Effect.runPromise(result).then(console.log)// Output:// Currently at index 0// Currently at index 1// Currently at index 2// Currently at index 3// Currently at index 4// undefinedSee
allfor combining multiple effects into one.
Signature
declare const forEach: { <B, E, R, S extends Iterable<any>, const Discard extends boolean = false>( f: (a: Arr.ReadonlyArray.Infer<S>, i: number) => Effect<B, E, R>, options?: { readonly concurrency?: Concurrency | undefined; readonly discard?: Discard | undefined } | undefined ): (self: S) => Effect<Discard extends false ? Arr.ReadonlyArray.With<S, B> : void, E, R> <B, E, R, S extends Iterable<any>, const Discard extends boolean = false>( self: S, f: (a: Arr.ReadonlyArray.Infer<S>, i: number) => Effect<B, E, R>, options?: { readonly concurrency?: Concurrency | undefined; readonly discard?: Discard | undefined } | undefined ): Effect<Discard extends false ? Arr.ReadonlyArray.With<S, B> : void, E, R>}Since v2.0.0
partition
Section titled “partition”Applies an effectful function to each element and partitions failures and successes.
Details
The returned tuple is [excluded, satisfying], where excluded contains
all failures and satisfying contains all successes.
This function runs every effect and never fails. Use concurrency to control
parallelism.
Example (Separating successes and failures)
import { Effect } from "effect"
const program = Effect.partition([0, 1, 2, 3], (n) => (n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)))
Effect.runPromise(program).then(console.log)// [ ["0 is even", "2 is even"], [1, 3] ]Signature
declare const partition: { <A, B, E, R>( f: (a: A, i: number) => Effect<B, E, R>, options?: { readonly concurrency?: Concurrency | undefined } ): (elements: Iterable<A>) => Effect<[excluded: Array<E>, satisfying: Array<B>], never, R> <A, B, E, R>( elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options?: { readonly concurrency?: Concurrency | undefined } ): Effect<[excluded: Array<E>, satisfying: Array<B>], never, R>}Since v2.0.0
replicate
Section titled “replicate”Returns an array of n identical effects.
When to use
Use when you need an array of identical effect values without running them yet.
Details
This only creates the array of effects. It does not run or collect them.
See
allfor running the returned effects and collecting resultsreplicateEffectfor repeating an effect and collecting results in one step with concurrency and discard options
Signature
declare const replicate: { (n: number): <A, E, R>(self: Effect<A, E, R>) => Array<Effect<A, E, R>> <A, E, R>(self: Effect<A, E, R>, n: number): Array<Effect<A, E, R>>}Since v2.0.0
replicateEffect
Section titled “replicateEffect”Performs this effect n times and collects results with Effect.all semantics.
When to use
Use when you want to run the repeated effects immediately, with optional concurrency control or result discarding.
Details
Use concurrency to control parallelism and discard: true to ignore results.
Example (Replicating an effect)
import { Console, Effect } from "effect"
const program = Effect.gen(function* () { const results = yield* Effect.replicateEffect(3)(Effect.succeed(1)) yield* Console.log(results)})Signature
declare const replicateEffect: { ( n: number, options?: { readonly concurrency?: Concurrency | undefined; readonly discard?: false | undefined } ): <A, E, R>(self: Effect<A, E, R>) => Effect<Array<A>, E, R> ( n: number, options: { readonly concurrency?: Concurrency | undefined; readonly discard: true } ): <A, E, R>(self: Effect<A, E, R>) => Effect<void, E, R> <A, E, R>( self: Effect<A, E, R>, n: number, options?: { readonly concurrency?: Concurrency | undefined; readonly discard?: false | undefined } ): Effect<Array<A>, E, R> <A, E, R>( self: Effect<A, E, R>, n: number, options: { readonly concurrency?: Concurrency | undefined; readonly discard: true } ): Effect<void, E, R>}Since v2.0.0
whileLoop
Section titled “whileLoop”Executes a body effect repeatedly while a condition holds true.
Example (Repeating an effectful loop)
import { Effect } from "effect"
let counter = 0
const program = Effect.whileLoop({ while: () => counter < 5, body: () => Effect.sync(() => ++counter), step: (n) => console.log(`Current count: ${n}`)})
Effect.runPromise(program)// Output:// Current count: 1// Current count: 2// Current count: 3// Current count: 4// Current count: 5Signature
declare const whileLoop: <A, E, R>(options: { readonly while: LazyArg<boolean> readonly body: LazyArg<Effect<A, E, R>> readonly step: (a: A) => void}) => Effect<void, E, R>Since v2.0.0
condition checking
Section titled “condition checking”isFailure
Section titled “isFailure”Determines whether an effect fails.
Details
Defects are not converted; if the effect dies, the resulting effect dies too.
Example (Checking whether an effect fails)
import { Console, Effect } from "effect"
const program = Effect.gen(function* () { const failed = yield* Effect.isFailure(Effect.fail("Uh oh!")) yield* Console.log(failed)})
Effect.runPromise(program)// Output: trueSignature
declare const isFailure: <A, E, R>(self: Effect<A, E, R>) => Effect<boolean, never, R>Since v2.0.0
isSuccess
Section titled “isSuccess”Returns whether an effect completes successfully.
Details
Returns false for failures in the error channel, but defects still fail the
effect.
Example (Checking whether an effect succeeds)
import { Console, Effect } from "effect"
const program = Effect.gen(function* () { const ok = yield* Effect.isSuccess(Effect.succeed("done")) const failed = yield* Effect.isSuccess(Effect.fail("Uh oh")) yield* Console.log(`ok: ${ok}`) yield* Console.log(`failed: ${failed}`)})
Effect.runPromise(program)// Output:// ok: true// failed: falseSignature
declare const isSuccess: <A, E, R>(self: Effect<A, E, R>) => Effect<boolean, never, R>Since v2.0.0
conditional operators
Section titled “conditional operators”Runs an effect conditionally based on the result of an effectful boolean condition.
When to use
Use when you need an effectful check to decide whether another effect should run while representing the skipped case explicitly.
Details
The condition effect is evaluated first. If it succeeds with true, the
source effect is run and its success value is wrapped in Option.some. If it
succeeds with false, the source effect is skipped and the result is
Option.none. If the condition effect fails, that failure is preserved.
Example (Conditionally running an effect)
import { Console, Effect } from "effect"
const shouldLog = true
const program = Effect.when(Console.log("Condition is true!"), Effect.succeed(shouldLog))
Effect.runPromise(program).then(console.log)// Output: "Condition is true!"// { _id: 'Option', _tag: 'Some', value: undefined }Signature
declare const when: { <E2 = never, R2 = never>( condition: Effect<boolean, E2, R2> ): <A, E, R>(self: Effect<A, E, R>) => Effect<Option<A>, E | E2, R | R2> <A, E, R, E2 = never, R2 = never>( self: Effect<A, E, R>, condition: Effect<boolean, E2, R2> ): Effect<Option<A>, E | E2, R | R2>}Since v2.0.0
constructors
Section titled “constructors”callback
Section titled “callback”Creates an Effect from a callback-based asynchronous API.
When to use
Use when you need to integrate APIs that complete through callbacks instead
of returning a Promise.
Details
The registration function receives a resume callback and, when requested,
an AbortSignal. Call resume at most once with the effect that should
complete the fiber; later calls are ignored. Return an optional cleanup
effect from the registration function to run if the fiber is interrupted.
Example (Integrating callback APIs)
import { Effect } from "effect"
const delay = (ms: number) => Effect.callback<void>((resume) => { const timeoutId = setTimeout(() => { resume(Effect.void) }, ms) // Cleanup function for interruption return Effect.sync(() => clearTimeout(timeoutId)) })
const program = delay(1000)Signature
declare const callback: <A, E = never, R = never>( register: ( this: Scheduler, resume: (effect: Effect<A, E, R>) => void, signal: AbortSignal ) => void | Effect<void, never, R>) => Effect<A, E, R>Since v4.0.0
Creates an effect that terminates a fiber with a specified error.
When to use
Use when you need an Effect to report an unrecoverable defect instead of a
typed error.
Details
The die function is used to signal a defect, which represents a critical
and unexpected error in the code. When invoked, it produces an effect that
does not handle the error and instead terminates the fiber.
The error channel of the resulting effect is of type never, indicating that
it cannot recover from this failure.
Example (Failing on division by zero)
import { Effect } from "effect"
const divide = (a: number, b: number) => b === 0 ? Effect.die(new Error("Cannot divide by zero")) : Effect.succeed(a / b)
// ┌─── Effect<number, never, never>// ▼const program = divide(1, 0)
Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) Error: Cannot divide by zero// ...stack trace...Signature
declare const die: (defect: unknown) => Effect<never>Since v2.0.0
Creates an Effect that represents a recoverable error.
When to use
Use to explicitly signal a recoverable error in an Effect.
Details
The error keeps propagating unless it is handled. You can handle tagged
errors with functions like catchTag or catchTags.
Example (Creating a failed effect)
import { Data, Effect } from "effect"
class OperationFailedError extends Data.TaggedError("OperationFailedError")<{}> {}
// ┌─── Effect<never, OperationFailedError, never>// ▼const failure = Effect.fail(new OperationFailedError())See
succeedto create an effect that represents a successful value.
Signature
declare const fail: <E>(error: E) => Effect<never, E>Since v2.0.0
failCause
Section titled “failCause”Creates an Effect that represents a failure with a specific Cause.
When to use
Use when you already have a full Cause and need to preserve defects,
interruptions, annotations, or combined failures in the effect’s failure
channel.
Details
This function allows you to create effects that fail with complex error structures, including multiple errors, defects, interruptions, and more.
Example (Failing with a full Cause)
import { Cause, Effect } from "effect"
const program = Effect.failCause(Cause.fail("Network error"))
Effect.runPromiseExit(program).then(console.log)// Output: { _id: 'Exit', _tag: 'Failure', cause: ... }Signature
declare const failCause: <E>(cause: Cause.Cause<E>) => Effect<never, E>Since v2.0.0
failCauseSync
Section titled “failCauseSync”Creates an Effect that represents a failure with a Cause computed lazily.
When to use
Use to defer computing a full Cause until the effect is run.
Details
The cause-producing function is evaluated each time the effect is executed.
Example (Lazily creating a Cause)
import { Cause, Effect } from "effect"
const program = Effect.failCauseSync(() => Cause.fail("Error computed at runtime"))
Effect.runPromiseExit(program).then(console.log)// Output: { _id: 'Exit', _tag: 'Failure', cause: ... }Signature
declare const failCauseSync: <E>(evaluate: LazyArg<Cause.Cause<E>>) => Effect<never, E>Since v2.0.0
failSync
Section titled “failSync”Creates an Effect that represents a recoverable error using a lazy evaluation.
When to use
Use to defer computing a recoverable error value until the effect is run.
Details
The error-producing function is evaluated each time the effect is executed.
Example (Lazily creating failures)
import { Data, Effect } from "effect"
class ProgramError extends Data.TaggedError("ProgramError")<{ readonly failedAt: Date }> {}
const program = Effect.failSync(() => new ProgramError({ failedAt: new Date() }))
Effect.runPromiseExit(program).then(console.log)// Output: { _id: 'Exit', _tag: 'Failure', cause: ... }Signature
declare const failSync: <E>(evaluate: LazyArg<E>) => Effect<never, E>Since v2.0.0
Provides a way to write effectful code using generator functions, simplifying control flow and error handling.
When to use
Use when you want to write effectful code that looks and behaves like synchronous code, while still handling asynchronous tasks, errors, and complex control flow such as loops and conditions.
Generator functions work similarly to async/await but keep errors,
requirements, and interruption in the Effect type. You can yield* values
from effects and return the final result at the end.
Example (Sequencing effects with generators)
import { Data, Effect } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (total: number, discountRate: number): Effect.Effect<number, DiscountRateError> => discountRate === 0 ? Effect.fail(new DiscountRateError()) : Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount(transactionAmount, discountRate) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})Signature
declare const gen: { <Eff extends Effect<any, any, any>, AEff>( f: () => Generator<Eff, AEff, never> ): Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never > <Self, Eff extends Effect<any, any, any>, AEff>( options: { readonly self: Self }, f: (this: Self) => Generator<Eff, AEff, never> ): Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >}Since v2.0.0
Returns an effect that will never produce anything. The moral equivalent of
while(true) {}, only without the wasted CPU cycles.
Example (Creating a never-ending effect)
import { Effect } from "effect"
// This effect will never completeconst program = Effect.never
// This will run forever (or until interrupted)// Effect.runPromise(program) // Never resolves
// Use with timeout for practical applicationsconst timedProgram = Effect.timeout(program, "1 second")Signature
declare const never: Effect<never, never, never>Since v2.0.0
promise
Section titled “promise”Creates an Effect that represents an asynchronous computation guaranteed to
succeed.
When to use
Use to convert a Promise into an Effect when the async operation is
guaranteed to succeed and will not reject.
Details
An optional AbortSignal can be provided to allow for interruption of the
wrapped Promise API.
Gotchas
The Promise must not reject. If it rejects, the rejection is treated as a
defect, not as a typed failure. Use tryPromise when rejection is expected.
Interruption aborts the provided AbortSignal, but the underlying
asynchronous operation only stops if it observes that signal.
Example (Wrapping a non-rejecting Promise)
import { Effect } from "effect"
const delay = (message: string) => Effect.promise<string>( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) )
// ┌─── Effect<string, never, never>// ▼const program = delay("Async operation completed successfully!")See
tryPromisefor a version that can handle failures.
Signature
declare const promise: <A>(evaluate: (signal: AbortSignal) => PromiseLike<A>) => Effect<A>Since v2.0.0
succeed
Section titled “succeed”Creates an Effect that always succeeds with a given value.
When to use
Use when an effect should complete successfully with a specific value without any errors or external dependencies.
Example (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)See
failto create an effect that represents a failure.
Signature
declare const succeed: <A>(value: A) => Effect<A>Since v2.0.0
succeedNone
Section titled “succeedNone”Returns an effect which succeeds with None.
Example (Succeeding with Option.none)
import { Effect } from "effect"
const program = Effect.succeedNone
Effect.runPromise(program).then(console.log)// Output: { _id: 'Option', _tag: 'None' }Signature
declare const succeedNone: Effect<Option<never>, never, never>Since v2.0.0
succeedSome
Section titled “succeedSome”Returns an effect which succeeds with the value wrapped in a Some.
Example (Succeeding with Option.some)
import { Effect } from "effect"
const program = Effect.succeedSome(42)
Effect.runPromise(program).then(console.log)// Output: { _id: 'Option', _tag: 'Some', value: 42 }Signature
declare const succeedSome: <A>(value: A) => Effect<Option<A>>Since v2.0.0
suspend
Section titled “suspend”Creates an Effect lazily, delaying construction until it is needed.
When to use
Use when you need to defer the evaluation of an effect until it is required.
Details
suspend takes a thunk that represents an effect and delays creating it
until the suspended effect is evaluated. This is useful for optimizing
expensive computations, managing circular dependencies such as recursive
functions, and helping TypeScript unify return types when branches construct
different effects. Any side effects or scoped captures inside the thunk are
re-executed on each invocation.
Example (Lazily evaluating side effects)
import { Effect } from "effect"
let i = 0
const bad = Effect.succeed(i++)
const good = Effect.suspend(() => Effect.succeed(i++))
console.log(Effect.runSync(bad)) // Output: 0console.log(Effect.runSync(bad)) // Output: 0
console.log(Effect.runSync(good)) // Output: 1console.log(Effect.runSync(good)) // Output: 2Example (Suspending recursive Fibonacci evaluation)
import { Effect } from "effect"
const blowsUp = (n: number): Effect.Effect<number> => n < 2 ? Effect.succeed(1) : Effect.zipWith(blowsUp(n - 1), blowsUp(n - 2), (a, b) => a + b)
// console.log(Effect.runSync(blowsUp(32)))// crash: JavaScript heap out of memory
const allGood = (n: number): Effect.Effect<number> => n < 2 ? Effect.succeed(1) : Effect.zipWith( Effect.suspend(() => allGood(n - 1)), Effect.suspend(() => allGood(n - 2)), (a, b) => a + b )
console.log(Effect.runSync(allGood(32)))// Output: 3524578Example (Helping TypeScript infer recursive effect types)
import { Effect } from "effect"
// Without suspend, TypeScript may struggle with type inference.// Inferred type:// (a: number, b: number) =>// Effect<never, Error, never> | Effect<number, never, never>const withoutSuspend = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b)
// Using suspend to unify return types.// Inferred type:// (a: number, b: number) => Effect<number, Error, never>const withSuspend = (a: number, b: number) => Effect.suspend(() => (b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b)))Signature
declare const suspend: <A, E, R>(effect: LazyArg<Effect<A, E, R>>) => Effect<A, E, R>Since v2.0.0
Creates an Effect that represents a synchronous side-effectful computation.
When to use
Use when you need to wrap a synchronous side-effectful operation that is not expected to throw.
Details
The provided function is evaluated lazily when the effect runs.
Gotchas
The function must not throw. If it throws, the thrown value is treated as a
defect, not as a typed failure. Use try when throwing is expected.
Example (Capturing synchronous logging in an Effect)
import { Effect } from "effect"
const log = (message: string) => Effect.sync(() => { console.log(message) // side effect })
// ┌─── Effect<void, never, never>// ▼const program = log("Hello, World!")See
| tryfor a version that can handle failures.
Signature
declare const sync: <A>(thunk: LazyArg<A>) => Effect<A>Since v2.0.0
Creates an Effect from a synchronous computation that may throw, mapping
thrown values into the error channel.
When to use
Use when you need to perform synchronous operations that might throw, such as parsing JSON, and want thrown exceptions captured as Effect errors.
Details
The thunk is evaluated when the effect runs. If it returns normally, the returned value becomes the success value. If it throws, the thrown value is mapped into the error channel.
Passing the thunk directly maps failures to Cause.UnknownError.
Passing { try, catch } uses catch to map failures to an error of type
E.
Gotchas
If catch throws while mapping the error, that thrown value is treated as
a defect. Return the error value you want in the error channel instead of
throwing it.
Example (Parsing JSON)
import { Effect } from "effect"
const parseJSON = (input: string) => Effect.try(() => JSON.parse(input))
// Success caseEffect.runPromise(parseJSON('{"name": "Alice"}')).then(console.log)// Output: { name: "Alice" }
// Failure case maps the thrown value to UnknownErrorEffect.runPromiseExit(parseJSON("invalid json")).then(console.log)Example (Mapping exceptions to a tagged error)
import { Data, Effect } from "effect"
class JsonParsingError extends Data.TaggedError("JsonParsingError")<{ readonly cause: unknown }> {}
const parseJSON = (input: string) => Effect.try({ try: () => JSON.parse(input), catch: (cause) => new JsonParsingError({ cause }) })
Effect.runPromiseExit(parseJSON("invalid json")).then(console.log)// Output: Exit.failure with custom Error messageSee
syncif the effectful computation is synchronous and does not throw errors.
Signature
declare const try: <A, E = Cause.UnknownError>(options: { readonly try: LazyArg<A>; readonly catch: (error: unknown) => E; } | LazyArg<A>) => Effect<A, E>Since v2.0.0
tryPromise
Section titled “tryPromise”Creates an Effect from an asynchronous computation that may throw or
reject, mapping failures into the error channel.
When to use
Use when you need to perform asynchronous operations that might fail, such as fetching data from an API, and want thrown exceptions or rejected promises captured as Effect errors.
Details
The promise thunk is evaluated when the effect runs. If it returns a promise that resolves, the resolved value becomes the success value. If the thunk throws before returning a promise, or if the returned promise rejects, the thrown or rejected value is mapped into the error channel.
Passing the thunk directly maps failures to Cause.UnknownError.
Passing { try, catch } uses catch to map failures to an error of type
E.
The thunk receives an AbortSignal that is aborted if the effect is
interrupted. The underlying asynchronous operation only stops if it observes
that signal.
Gotchas
If catch throws while mapping the error, that thrown value is treated as a
defect. Return the error value you want in the error channel instead of
throwing it.
Example (Wrapping a fetch request that may fail)
import { Effect } from "effect"
const getTodo = (id: number) => // Will catch any errors and propagate them as UnknownError Effect.tryPromise(() => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`))
// ┌─── Effect<Response, UnknownError, never>// ▼const program = getTodo(1)Example (Mapping Promise rejections to a tagged error)
import { Data, Effect } from "effect"
class TodoFetchError extends Data.TaggedError("TodoFetchError")<{ readonly cause: unknown }> {}
const getTodo = (id: number) => Effect.tryPromise({ try: () => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`), // remap the error catch: (cause) => new TodoFetchError({ cause }) })
// ┌─── Effect<Response, TodoFetchError, never>// ▼const program = getTodo(1)See
promiseif the effectful computation is asynchronous and does not throw errors.
Signature
declare const tryPromise: <A, E = Cause.UnknownError>( options: | { readonly try: (signal: AbortSignal) => PromiseLike<A>; readonly catch: (error: unknown) => E } | ((signal: AbortSignal) => PromiseLike<A>)) => Effect<A, E>Since v2.0.0
undefined
Section titled “undefined”Returns an effect that succeeds with undefined.
Signature
declare const undefined: Effect<undefined, never, never>Since v4.0.0
Returns an effect that succeeds with void.
Signature
declare const void: Effect<void, never, never>Since v2.0.0
withFiber
Section titled “withFiber”Provides access to the current fiber within an effect computation.
Example (Reading the current fiber)
import { Effect } from "effect"
const program = Effect.withFiber((fiber) => Effect.succeed(`Fiber ID: ${fiber.id}`))
Effect.runPromise(program).then(console.log)// Output: Fiber ID: 1Signature
declare const withFiber: <A, E = never, R = never>( evaluate: (fiber: Fiber<unknown, unknown>) => Effect<A, E, R>) => Effect<A, E, R>Since v4.0.0
yieldNow
Section titled “yieldNow”Yields control back to the Effect runtime, allowing other fibers to execute.
Example (Yielding to other fibers)
import { Effect } from "effect"
const program = Effect.gen(function* () { console.log("Before yield") yield* Effect.yieldNow console.log("After yield")})
Effect.runPromise(program)Signature
declare const yieldNow: Effect<void, never, never>Since v2.0.0
yieldNowWith
Section titled “yieldNowWith”Yields control back to the Effect runtime with a specified priority, allowing other fibers to execute.
Example (Yielding with priority)
import { Effect } from "effect"
const program = Effect.gen(function* () { console.log("High priority task") yield* Effect.yieldNowWith(10) // Higher priority console.log("Continued after yield")})
Effect.runPromise(program)Signature
declare const yieldNowWith: (priority?: number) => Effect<void>Since v4.0.0
context
Section titled “context”provideService
Section titled “provideService”Provides one concrete service implementation to an effect.
When to use
Use to satisfy one service requirement with an already-built implementation.
Details
The service requirement identified by the Context.Key is removed from the
effect requirements after the implementation is provided.
Example (Providing a service value)
import { Console, Context, Effect } from "effect"
// Define a service for configurationconst Config = Context.Service<{ apiUrl: string timeout: number}>("Config")
const fetchData = Effect.gen(function* () { const config = yield* Effect.service(Config) yield* Console.log(`Fetching from: ${config.apiUrl}`) yield* Console.log(`Timeout: ${config.timeout}ms`) return "data"})
// Provide the service implementationconst program = Effect.provideService(fetchData, Config, { apiUrl: "https://api.example.com", timeout: 5000})
Effect.runPromise(program).then(console.log)// Output:// Fetching from: https://api.example.com// Timeout: 5000ms// dataSee
providefor providing multiple layers to an effect.provideServiceEffectfor acquiring the service implementation effectfully.provideContextfor providing a complete context.
Signature
declare const provideService: { <I, S>( service: Context.Key<I, S> ): { (implementation: S): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, I>> <A, E, R>(self: Effect<A, E, R>, implementation: S): Effect<A, E, Exclude<R, I>> } <I, S>(service: Context.Key<I, S>, implementation: S): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, I>> <A, E, R, I, S>(self: Effect<A, E, R>, service: Context.Key<I, S>, implementation: S): Effect<A, E, Exclude<R, I>>}Since v2.0.0
provideServiceEffect
Section titled “provideServiceEffect”Provides one service to an effect using an effectful acquisition.
When to use
Use when the service implementation must be created by an effect and its acquisition failure should remain in the returned effect.
Details
provideServiceEffect runs the acquisition effect to produce the service
implementation, removes that service from the wrapped effect’s requirements,
and leaves any other requirements to be provided later. Acquisition failures
are included in the returned effect’s error channel.
Example (Providing a service with an effect)
import { Console, Context, Effect } from "effect"
// Define a database connection serviceinterface DatabaseConnection { readonly query: (sql: string) => Effect.Effect<string>}const Database = Context.Service<DatabaseConnection>("Database")
// Effect that creates a database connectionconst createConnection = Effect.gen(function* () { yield* Console.log("Establishing database connection...") yield* Effect.sleep("100 millis") // Simulate connection time yield* Console.log("Database connected!") return { query: (sql: string) => Effect.succeed(`Result for: ${sql}`) }})
const program = Effect.gen(function* () { const db = yield* Effect.service(Database) return yield* db.query("SELECT * FROM users")})
// Provide the service through an effectconst withDatabase = Effect.provideServiceEffect(program, Database, createConnection)
Effect.runPromise(withDatabase).then(console.log)// Output:// Establishing database connection...// Database connected!// Result for: SELECT * FROM usersSignature
declare const provideServiceEffect: { <I, S, E2, R2>( service: Context.Key<I, S>, acquire: Effect<S, E2, R2> ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, Exclude<R, I> | R2> <A, E, R, I, S, E2, R2>( self: Effect<A, E, R>, service: Context.Key<I, S>, acquire: Effect<S, E2, R2> ): Effect<A, E | E2, Exclude<R, I> | R2>}Since v2.0.0
service
Section titled “service”Accesses a service from the context.
Example (Accessing a required service)
import { Context, Effect } from "effect"
interface Database { readonly query: (sql: string) => Effect.Effect<string>}
const Database = Context.Service<Database>("Database")
const program = Effect.gen(function* () { const db = yield* Effect.service(Database) return yield* db.query("SELECT * FROM users")})Signature
declare const service: <I, S>(service: Context.Key<I, S>) => Effect<S, never, I>Since v4.0.0
serviceOption
Section titled “serviceOption”Optionally accesses a service from the environment.
When to use
Use to read an optional dependency from the current context without making that dependency part of the effect’s required environment.
Details
This function attempts to access a service from the environment. If the
service is available, it returns Some(service). If the service is not
available, it returns None. Unlike service, this function does not
require the service to be present in the environment.
Example (Accessing an optional service)
import { Context, Effect, Option } from "effect"
// Define a service keyconst Logger = Context.Service<{ log: (msg: string) => void}>("Logger")
// Use serviceOption to optionally access the loggerconst program = Effect.gen(function* () { const maybeLogger = yield* Effect.serviceOption(Logger)
if (Option.isSome(maybeLogger)) { maybeLogger.value.log("Service is available") } else { console.log("Service not available") }})Signature
declare const serviceOption: <I, S>(key: Context.Key<I, S>) => Effect<Option<S>>Since v2.0.0
updateContext
Section titled “updateContext”Provides part of the required context while leaving the rest unchanged.
Details
This function allows you to transform the context required by an effect, providing part of the context and leaving the rest to be fulfilled later.
Example (Updating the context before running)
import { Context, Effect } from "effect"
// Define servicesconst Logger = Context.Service<{ log: (msg: string) => void}>("Logger")const Config = Context.Service<{ name: string}>("Config")
const program = Effect.service(Config).pipe(Effect.map((config) => `Hello ${config.name}!`))
// Transform services by providing Config while keeping Logger requirementconst configured = program.pipe( Effect.updateContext((context: Context.Context<typeof Logger>) => Context.add(context, Config, { name: "World" })))
// The effect now requires only Logger serviceconst result = Effect.provideService(configured, Logger, { log: (msg) => console.log(msg)})Signature
declare const updateContext: { <R2, R>( f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>> ): <A, E>(self: Effect<A, E, R>) => Effect<A, E, R2> <A, E, R, R2>( self: Effect<A, E, R>, f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>> ): Effect<A, E, R2>}Since v4.0.0
updateService
Section titled “updateService”Runs an effect with a service implementation transformed by the provided function.
Details
The service must be available in the effect’s context; updateService
replaces it for the wrapped effect with the value returned by the updater.
Example (Replacing a service for one effect)
import { Console, Context, Effect } from "effect"
// Define a counter serviceconst Counter = Context.Service<{ count: number }>("Counter")
const program = Effect.gen(function* () { const updatedCounter = yield* Effect.service(Counter) yield* Console.log(`Updated count: ${updatedCounter.count}`) return updatedCounter.count}).pipe(Effect.updateService(Counter, (counter) => ({ count: counter.count + 1 })))
// Provide initial service and runconst result = Effect.provideService(program, Counter, { count: 0 })Effect.runPromise(result).then(console.log)// Output: Updated count: 1// 1Signature
declare const updateService: { <I, A>(service: Context.Key<I, A>, f: (value: A) => A): <XA, E, R>(self: Effect<XA, E, R>) => Effect<XA, E, R | I> <XA, E, R, I, A>(self: Effect<XA, E, R>, service: Context.Key<I, A>, f: (value: A) => A): Effect<XA, E, R | I>}Since v2.0.0
converting
Section titled “converting”fromNullishOr
Section titled “fromNullishOr”Converts a nullable value to an Effect, failing with a NoSuchElementError
when the value is null or undefined.
Example (Failing on nullish values)
import { Console, Effect } from "effect"
const program = Effect.fn( function* (input: string | null) { const value = yield* Effect.fromNullishOr(input) yield* Console.log(value) }, Effect.catch(() => Console.log("missing")))
Effect.runPromise(program(null))// Output: missingEffect.runPromise(program("hello"))// Output: helloSignature
declare const fromNullishOr: <A>(value: A) => Effect<NonNullable<A>, Cause.NoSuchElementError>Since v4.0.0
fromOption
Section titled “fromOption”Converts an Option into an Effect.
When to use
Use when absence should become a typed NoSuchElementError in the effect error
channel.
Details
Option.some becomes a successful effect with the contained value, while
Option.none becomes a failed effect. By default the failure is a
NoSuchElementError, but you can provide an onNone callback to customize
the error value.
Example (Converting an Option into an Effect)
import { Effect, Option } from "effect"
const some = Option.some(42)const none = Option.none()
const effect1 = Effect.fromOption(some)const effect2 = Effect.fromOption(none)const effect3 = Effect.fromOption(none, () => new Error("missing"))
Effect.runPromise(effect1).then(console.log) // 42Effect.runPromiseExit(effect2).then(console.log)// { _id: 'Exit', _tag: 'Failure', cause: { _id: 'Cause', _tag: 'Fail', failure: { _id: 'NoSuchElementError' } } }Signature
declare const fromOption: <Arg extends Option<unknown> | LazyArg<unknown>, E = Cause.NoSuchElementError>( arg: Arg, ...rest: [Arg] extends [Option<unknown>] ? [onNone?: LazyArg<E>] : []) => [Arg] extends [Option<infer A>] ? Effect<A, E> : [Arg] extends [LazyArg<infer E>] ? <A>(option: Option<A>) => Effect<A, E> : neverSince v4.0.0
fromResult
Section titled “fromResult”Converts a Result to an Effect.
Example (Converting a Result into an Effect)
import { Effect, Result } from "effect"
const success = Result.succeed(42)const failure = Result.fail("Something went wrong")
const effect1 = Effect.fromResult(success)const effect2 = Effect.fromResult(failure)
Effect.runPromise(effect1).then(console.log) // 42Effect.runPromiseExit(effect2).then(console.log)// { _id: 'Exit', _tag: 'Failure', cause: { _id: 'Cause', _tag: 'Fail', failure: 'Something went wrong' } }Signature
declare const fromResult: <A, E>(result: Result.Result<A, E>) => Effect<A, E>Since v4.0.0
transposeOption
Section titled “transposeOption”Converts an Option of an Effect into an Effect of an Option.
When to use
Use when an effect should run only when an optional value is present, while
preserving absence as a successful None.
Details
Nonebecomes an effect that succeeds withNoneSome(effect)runs the inner effect and wraps its success value inSome- Inner failures are preserved in the resulting effect
Example (Transposing an Option of an Effect)
import { Effect, Option } from "effect"
const some = Option.some(Effect.succeed(42))
// ┌─── Effect<Option<number>, never, never>// ▼const program = Effect.transposeOption(some)
Effect.runPromise(program).then(console.log)// Output: { _id: 'Option', _tag: 'Some', value: 42 }Signature
declare const transposeOption: <A = never, E = never, R = never>( self: Option<Effect<A, E, R>>) => Effect<Option<A>, E, R>Since v3.13.0
converting failures to defects
Section titled “converting failures to defects”Converts typed failures from the error channel into defects, removing the error type from the returned effect.
When to use
Use when you need to turn an Effect typed failure that represents an
unrecoverable bug or invalid state into a defect.
Example (Converting typed failures into defects)
import { Data, Effect } from "effect"
class DivideByZeroError extends Data.TaggedError("DivideByZeroError")<{}> {}
const divide = (a: number, b: number) => (b === 0 ? Effect.fail(new DivideByZeroError()) : Effect.succeed(a / b))
// ┌─── Effect<number, never, never>// ▼const program = Effect.orDie(divide(1, 0))
Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) DivideByZeroError// ...stack trace...Signature
declare const orDie: <A, E, R>(self: Effect<A, E, R>) => Effect<A, never, R>Since v2.0.0
delays & timeouts
Section titled “delays & timeouts”Returns an effect that is delayed from this effect by the specified
Duration.
Example (Delaying an effect)
import { Console, Effect } from "effect"
const program = Effect.delay(Console.log("Delayed message"), "1 second")
Effect.runFork(program)// Waits 1 second, then prints: "Delayed message"Signature
declare const delay: { (duration: Duration.Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>(self: Effect<A, E, R>, duration: Duration.Input): Effect<A, E, R>}Since v2.0.0
Returns an effect that suspends the current fiber for the specified duration without blocking a JavaScript thread.
Example (Pausing without blocking)
import { Console, Effect } from "effect"
const program = Effect.gen(function* () { yield* Console.log("Start") yield* Effect.sleep("2 seconds") yield* Console.log("End")})
Effect.runFork(program)// Output: "Start" (immediately)// Output: "End" (after 2 seconds)Signature
declare const sleep: (duration: Duration.Input) => Effect<void>Since v2.0.0
Returns the runtime duration of an effect together with its result.
Details
The original success, failure, or interruption is preserved; only the success value is paired with the duration.
Example (Measuring execution time)
import { Console, Duration, Effect } from "effect"
const program = Effect.gen(function* () { const [duration, value] = yield* Effect.timed(Effect.succeed("ok")) yield* Console.log(`took ${Duration.toMillis(duration)}ms: ${value}`)})Signature
declare const timed: <A, E, R>(self: Effect<A, E, R>) => Effect<[duration: Duration.Duration, result: A], E, R>Since v2.0.0
timeout
Section titled “timeout”Adds a time limit to an effect, triggering a timeout if the effect exceeds the duration.
When to use
Use when you need a timeout of an Effect to be represented as a typed
failure.
Details
The timeout function allows you to specify a time limit for an
effect’s execution. If the effect does not complete within the given time, a
TimeoutException is raised. This can be useful for controlling how long
your program waits for a task to finish, ensuring that it doesn’t hang
indefinitely if the task takes too long.
Gotchas
If the timeout wins, the source effect is interrupted.
Example (Failing when work takes too long)
import { Effect } from "effect"
const task = Effect.gen(function* () { console.log("Start processing...") yield* Effect.sleep("2 seconds") // Simulates a delay in processing console.log("Processing complete.") return "Result"})
// Output will show a TimeoutException as the task takes longer// than the specified timeout durationconst timedEffect = task.pipe(Effect.timeout("1 second"))
Effect.runPromiseExit(timedEffect).then(console.log)// Output:// Start processing...// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// _tag: 'Fail',// failure: { _tag: 'TimeoutException' }// }// }See
timeoutOptionfor returningOption.noneon timeout.timeoutOrElsefor a version that allows specifying both success and timeout handlers.
Signature
declare const timeout: { (duration: Duration.Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | Cause.TimeoutError, R> <A, E, R>(self: Effect<A, E, R>, duration: Duration.Input): Effect<A, E | Cause.TimeoutError, R>}Since v2.0.0
timeoutOption
Section titled “timeoutOption”Runs an effect with a time limit and represents only the timeout case as
Option.none.
When to use
Use when a timeout of an Effect should be handled as Option.none.
Details
If the source effect succeeds before the timeout, the returned effect
succeeds with Option.some(value). If the timeout wins, the source effect is
interrupted and the returned effect succeeds with Option.none. If the
source effect fails before the timeout, that failure is preserved.
Example (Returning None on timeout)
import { Effect } from "effect"
const task = Effect.gen(function* () { console.log("Start processing...") yield* Effect.sleep("2 seconds") // Simulates a delay in processing console.log("Processing complete.") return "Result"})
const timedOutEffect = Effect.all([ task.pipe(Effect.timeoutOption("3 seconds")), task.pipe(Effect.timeoutOption("1 second"))])
Effect.runPromise(timedOutEffect).then(console.log)// Output:// Start processing...// Processing complete.// Start processing...// [// { _id: 'Option', _tag: 'Some', value: 'Result' },// { _id: 'Option', _tag: 'None' }// ]See
timeoutfor a version that raises aTimeoutException.timeoutOrElsefor a version that allows specifying both success and timeout handlers.
Signature
declare const timeoutOption: { (duration: Duration.Input): <A, E, R>(self: Effect<A, E, R>) => Effect<Option<A>, E, R> <A, E, R>(self: Effect<A, E, R>, duration: Duration.Input): Effect<Option<A>, E, R>}Since v3.1.0
timeoutOrElse
Section titled “timeoutOrElse”Applies a timeout to an effect, with a fallback effect executed if the timeout is reached.
When to use
Use when a timeout of an Effect should switch to a fallback effect.
Details
The fallback effect is created lazily by orElse and may introduce its own
success, failure, and requirement types.
Gotchas
If the timeout wins, the source effect is interrupted before the fallback is run.
Example (Falling back on timeout)
import { Console, Effect } from "effect"
const slowQuery = Effect.gen(function* () { yield* Console.log("Starting database query...") yield* Effect.sleep("5 seconds") return "Database result"})
// Use cached data as fallback when timeout is reachedconst program = Effect.timeoutOrElse(slowQuery, { duration: "2 seconds", orElse: () => Effect.gen(function* () { yield* Console.log("Query timed out, using cached data") return "Cached result" })})
Effect.runPromise(program).then(console.log)// Output:// Starting database query...// Query timed out, using cached data// Cached resultSee
timeoutfor failing with aTimeoutException.timeoutOptionfor returningOption.noneon timeout.
Signature
declare const timeoutOrElse: { <A2, E2, R2>(options: { readonly duration: Duration.Input readonly orElse: LazyArg<Effect<A2, E2, R2>> }): <A, E, R>(self: Effect<A, E, R>) => Effect<A | A2, E | E2, R | R2> <A, E, R, A2, E2, R2>( self: Effect<A, E, R>, options: { readonly duration: Duration.Input; readonly orElse: LazyArg<Effect<A2, E2, R2>> } ): Effect<A | A2, E | E2, R | R2>}Since v4.0.0
do notation
Section titled “do notation”Effect that succeeds with an empty record {}, used as the starting point
for do notation chains.
Example (Starting do notation)
import { Effect, pipe } from "effect"
const program = pipe( Effect.Do, Effect.bind("x", () => Effect.succeed(2)), Effect.bind("y", ({ x }) => Effect.succeed(x + 1)), Effect.let("sum", ({ x, y }) => x + y))Signature
declare const Do: Effect<{}, never, never>Since v2.0.0
Adds an Effect value to the do notation record under a given name.
When to use
Use to sequence an effectful step in a do-notation pipeline when that step depends on fields already accumulated in the record and its success value should be stored under a name.
Details
The function receives the current record, runs the returned effect after the
input effect succeeds, and inserts its success value under name. The
resulting effect combines the error and service requirements of both steps.
Gotchas
Binding a name that already exists replaces that field in the resulting record.
See
Dofor starting from an empty do-notation recordbindTofor naming the success value of an existing effectgenfor generator-based sequencing without accumulating a record
Signature
declare const bind: { <N extends string, A extends Record<string, any>, B, E2, R2>( name: N, f: (a: NoInfer<A>) => Effect<B, E2, R2> ): <E, R>(self: Effect<A, E, R>) => Effect<Simplify<Omit<A, N> & Record<N, B>>, E | E2, R | R2> <A extends Record<string, any>, E, R, B, E2, R2, N extends string>( self: Effect<A, E, R>, name: N, f: (a: NoInfer<A>) => Effect<B, E2, R2> ): Effect<Simplify<Omit<A, N> & Record<N, B>>, E | E2, R | R2>}Since v2.0.0
bindTo
Section titled “bindTo”Gives a name to the success value of an Effect, creating a single-key
record used in do notation pipelines.
When to use
Use to start a do-notation pipeline from an existing Effect when its
success value should become the first named field in the accumulated record.
See
Dofor starting from an empty accumulated recordbindfor adding fields produced by effects
Signature
declare const bindTo: { <N extends string>(name: N): <A, E, R>(self: Effect<A, E, R>) => Effect<{ [K in N]: A }, E, R> <A, E, R, N extends string>(self: Effect<A, E, R>, name: N): Effect<{ [K in N]: A }, E, R>}Since v2.0.0
Adds a computed plain value to the do notation record.
When to use
Use to add a derived, synchronous value to a do-notation pipeline when it
depends on fields already accumulated in the record and does not need to run
another Effect.
Details
The new field is added with object spreading. If the name already exists in the record, the computed value replaces it in the returned type.
See
bindfor adding fields produced by effectsbindTofor naming an existing success valueDofor starting from an empty accumulated recordgenfor sequencing without accumulating a record
Signature
declare const let: { <N extends string, A extends Record<string, any>, B>( name: N, f: (a: NoInfer<A>) => B ): <E, R>(self: Effect<A, E, R>) => Effect<Simplify<Omit<A, N> & Record<N, B>>, E, R> <A extends Record<string, any>, E, R, B, N extends string>( self: Effect<A, E, R>, name: N, f: (a: NoInfer<A>) => B ): Effect<Simplify<Omit<A, N> & Record<N, B>>, E, R>}Since v2.0.0
catchEager
Section titled “catchEager”Applies catch eagerly when an effect is already resolved.
When to use
Use when an already-resolved failed effect should recover immediately while pending effects still use regular error recovery.
Details
Success effects pass through unchanged because there is no error to catch.
Failure effects apply the catch function immediately, and pending effects
fall back to regular catch behavior.
Example (Catching failures eagerly when possible)
import { Effect } from "effect"
// For resolved failure effects, the catch function is applied immediatelyconst failed = Effect.fail("original error")const recovered = Effect.catchEager(failed, (err: string) => Effect.succeed(`recovered from: ${err}`)) // Applied eagerly
// For success effects, returns success as-isconst success = Effect.succeed(42)const unchanged = Effect.catchEager(success, (err: string) => Effect.succeed(`recovered from: ${err}`)) // Returns success as-is
// For pending effects, behaves like regular catchconst pending = Effect.delay(Effect.fail("error"), "100 millis")const recoveredPending = Effect.catchEager(pending, (err: string) => Effect.succeed(`recovered from: ${err}`)) // Uses regular catchSignature
declare const catchEager: { <E, B, E2, R2>(f: (e: NoInfer<E>) => Effect<B, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A | B, E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: (e: NoInfer<E>) => Effect<B, E2, R2>): Effect<A | B, E2, R | R2>}Since v4.0.0
flatMapEager
Section titled “flatMapEager”Applies flatMap eagerly when an effect is already resolved.
When to use
Use when an already-resolved successful effect should bind immediately to the next effect while pending effects still use regular flat mapping.
Details
Success effects apply the flatMap function immediately. Failure effects pass
through unchanged, and pending effects fall back to regular flatMap
behavior.
Example (Flat mapping eagerly when possible)
import { Effect } from "effect"
// For resolved effects, the flatMap is applied immediatelyconst resolved = Effect.succeed(5)const flatMapped = Effect.flatMapEager(resolved, (n) => Effect.succeed(n * 2)) // Applied eagerly
// For pending effects, behaves like regular flatMapconst pending = Effect.delay(Effect.succeed(5), "100 millis")const flatMappedPending = Effect.flatMapEager(pending, (n) => Effect.succeed(n * 2)) // Uses regular flatMapSignature
declare const flatMapEager: { <A, B, E2, R2>(f: (a: A) => Effect<B, E2, R2>): <E, R>(self: Effect<A, E, R>) => Effect<B, E | E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: (a: A) => Effect<B, E2, R2>): Effect<B, E | E2, R | R2>}Since v4.0.0
fnUntracedEager
Section titled “fnUntracedEager”Creates untraced function effects with eager evaluation optimization.
Details
Executes generator functions eagerly when all yielded effects are synchronous, stopping at the first async effect and deferring to normal execution.
Example (Defining eager untraced effect functions)
import { Effect } from "effect"
const computation = Effect.fnUntracedEager(function* () { yield* Effect.succeed(1) yield* Effect.succeed(2) return "computed eagerly"})
const effect = computation() // Executed immediately if all effects are syncSignature
declare const fnUntracedEager: fn.UntracedSince v4.0.0
mapBothEager
Section titled “mapBothEager”Applies mapBoth eagerly when an effect is already resolved.
When to use
Use when an already-resolved effect should transform either success or failure immediately while pending effects still use regular channel mapping.
Details
Success effects apply onSuccess immediately, and failure effects apply
onFailure immediately. Pending effects fall back to regular mapBoth
behavior.
Example (Mapping both channels eagerly when possible)
import { Effect } from "effect"
// For resolved effects, the appropriate mapping is applied immediatelyconst success = Effect.succeed(5)const mapped = Effect.mapBothEager(success, { onFailure: (err: string) => `Failed: ${err}`, onSuccess: (n: number) => n * 2}) // onSuccess applied eagerly
const failure = Effect.fail("error")const mappedError = Effect.mapBothEager(failure, { onFailure: (err: string) => `Failed: ${err}`, onSuccess: (n: number) => n * 2}) // onFailure applied eagerlySignature
declare const mapBothEager: { <E, E2, A, A2>(options: { readonly onFailure: (e: E) => E2 readonly onSuccess: (a: A) => A2 }): <R>(self: Effect<A, E, R>) => Effect<A2, E2, R> <A, E, R, E2, A2>( self: Effect<A, E, R>, options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 } ): Effect<A2, E2, R>}Since v4.0.0
mapEager
Section titled “mapEager”Applies map eagerly when an effect is already resolved.
When to use
Use when an already-resolved effect should apply a success transformation immediately while pending effects still use regular mapping.
Details
Success effects apply the mapping function immediately. Failure effects pass
through unchanged, and pending effects fall back to regular map behavior.
Example (Mapping already completed effects)
import { Effect } from "effect"
// For resolved effects, the mapping is applied immediatelyconst resolved = Effect.succeed(5)const mapped = Effect.mapEager(resolved, (n) => n * 2) // Applied eagerly
// For pending effects, behaves like regular mapconst pending = Effect.delay(Effect.succeed(5), "100 millis")const mappedPending = Effect.mapEager(pending, (n) => n * 2) // Uses regular mapSignature
declare const mapEager: { <A, B>(f: (a: A) => B): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R> <A, E, R, B>(self: Effect<A, E, R>, f: (a: A) => B): Effect<B, E, R>}Since v4.0.0
mapErrorEager
Section titled “mapErrorEager”Applies mapError eagerly when an effect is already resolved.
When to use
Use when an already-resolved failed effect should apply an error transformation immediately while pending effects still use regular error mapping.
Details
Success effects pass through unchanged because there is no error to
transform. Failure effects apply the mapping function immediately, and
pending effects fall back to regular mapError behavior.
Example (Mapping errors eagerly when possible)
import { Effect } from "effect"
// For resolved failure effects, the error mapping is applied immediatelyconst failed = Effect.fail("original error")const mapped = Effect.mapErrorEager(failed, (err: string) => `mapped: ${err}`) // Applied eagerly
// For pending effects, behaves like regular mapErrorconst pending = Effect.delay(Effect.fail("error"), "100 millis")const mappedPending = Effect.mapErrorEager(pending, (err: string) => `mapped: ${err}`) // Uses regular mapErrorSignature
declare const mapErrorEager: { <E, E2>(f: (e: E) => E2): <A, R>(self: Effect<A, E, R>) => Effect<A, E2, R> <A, E, R, E2>(self: Effect<A, E, R>, f: (e: E) => E2): Effect<A, E2, R>}Since v4.0.0
effectify
Section titled “effectify”effectify
Section titled “effectify”Converts an error-first callback API into a function that returns an
Effect.
Details
The original function is called with the supplied arguments plus a final
callback. A non-null callback error fails the returned effect, while a
successful callback value becomes the effect success. Use onError to map
callback errors and onSyncError to turn synchronous throws into typed
failures; otherwise synchronous throws become defects.
Example (Converting callbacks to effects)
import { Effect } from "effect"import * as fs from "fs"
// Convert Node.js readFile to an Effectconst readFile = Effect.effectify(fs.readFile)
// Use the effectified functionconst program = readFile("package.json", "utf8")
Effect.runPromise(program).then(console.log)// Output: contents of package.jsonExample (Mapping callback errors to typed failures)
import { Effect } from "effect"import * as fs from "fs"
const readFile = Effect.effectify( fs.readFile, (error, args) => new Error(`Failed to read file ${args[0]}: ${error.message}`))
const program = readFile("nonexistent.txt", "utf8")
Effect.runPromiseExit(program).then(console.log)// Output: Exit.failure with custom error messageSignature
declare const effectify: { <F extends (...args: Array<any>) => any>(fn: F): Effectify.Effectify<F, Effectify.EffectifyError<F>> <F extends (...args: Array<any>) => any, E>( fn: F, onError: (error: Effectify.EffectifyError<F>, args: Parameters<F>) => E ): Effectify.Effectify<F, E> <F extends (...args: Array<any>) => any, E, E2>( fn: F, onError: (error: Effectify.EffectifyError<F>, args: Parameters<F>) => E, onSyncError: (error: unknown, args: Parameters<F>) => E2 ): Effectify.Effectify<F, E | E2>}Since v4.0.0
environment
Section titled “environment”context
Section titled “context”Returns the complete context.
When to use
Use to read the complete Context available to the current effect.
Details
This function allows you to access all services that are currently available in the effect’s environment. This can be useful for debugging, introspection, or when you need to pass the entire context to another function.
Example (Reading the full context)
import { Console, Context, Effect, Option } from "effect"
const Logger = Context.Service<{ log: (msg: string) => void}>("Logger")const Database = Context.Service<{ query: (sql: string) => string}>("Database")
const program = Effect.gen(function* () { const allServices = yield* Effect.context()
// Check if specific services are available const loggerOption = Context.getOption(allServices, Logger) const databaseOption = Context.getOption(allServices, Database)
yield* Console.log(`Logger available: ${Option.isSome(loggerOption)}`) yield* Console.log(`Database available: ${Option.isSome(databaseOption)}`)})
const context = Context.make(Logger, { log: console.log }).pipe(Context.add(Database, { query: () => "result" }))
const provided = Effect.provideContext(program, context)See
contextWithfor deriving an effect from the complete contextservicefor reading one service from the context
Signature
declare const context: <R = never>() => Effect<Context.Context<R>, never, R>Since v2.0.0
contextWith
Section titled “contextWith”Transforms the current context using the provided function.
When to use
Use to derive an effect from the complete Context.
Details
This function allows you to access the complete context and perform computations based on all available services. This is useful when you need to conditionally execute logic based on what services are available.
Example (Deriving values from the context)
import { Console, Context, Effect, Option } from "effect"
const Logger = Context.Service<{ log: (msg: string) => void}>("Logger")const Cache = Context.Service<{ get: (key: string) => string | null}>("Cache")
const program = Effect.contextWith((services) => { const cacheOption = Context.getOption(services, Cache) const hasCache = Option.isSome(cacheOption)
if (hasCache) { return Effect.gen(function* () { const cache = yield* Effect.service(Cache) yield* Console.log("Using cached data") return cache.get("user:123") || "default" }) } else { return Effect.gen(function* () { yield* Console.log("No cache available, using fallback") return "fallback data" }) }})
const withCache = Effect.provideService(program, Cache, { get: () => "cached_value"})See
contextfor reading the complete context as a valueservicefor reading one service from the context
Signature
declare const contextWith: <R, A, E, R2>(f: (context: Context.Context<R>) => Effect<A, E, R2>) => Effect<A, E, R | R2>Since v2.0.0
provide
Section titled “provide”Provides dependencies to an effect using layers or a context. Use options.local
to build the layer every time; by default, layers are shared between provide
calls.
Example (Providing dependencies with a layer)
import { Context, Effect, Layer } from "effect"
interface Database { readonly query: (sql: string) => Effect.Effect<string>}
const Database = Context.Service<Database>("Database")
const DatabaseLive = Layer.succeed(Database)({ query: Effect.fn("Database.query")((sql: string) => Effect.succeed(`Result for: ${sql}`))})
const program = Effect.gen(function* () { const db = yield* Database return yield* db.query("SELECT * FROM users")})
const provided = Effect.provide(program, DatabaseLive)
Effect.runPromise(provided).then(console.log)// Output: "Result for: SELECT * FROM users"Signature
declare const provide: { <const Layers extends [Layer.Any, ...Array<Layer.Any>]>( layers: Layers, options?: { readonly local?: boolean | undefined } | undefined ): <A, E, R>( self: Effect<A, E, R> ) => Effect< A, E | Layer.Error<Layers[number]>, Layer.Services<Layers[number]> | Exclude<R, Layer.Success<Layers[number]>> > <ROut, E2, RIn>( layer: Layer.Layer<ROut, E2, RIn>, options?: { readonly local?: boolean | undefined } | undefined ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, RIn | Exclude<R, ROut>> <R2>(context: Context.Context<R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, R2>> <A, E, R, const Layers extends [Layer.Any, ...Array<Layer.Any>]>( self: Effect<A, E, R>, layers: Layers, options?: { readonly local?: boolean | undefined } | undefined ): Effect< A, E | Layer.Error<Layers[number]>, Layer.Services<Layers[number]> | Exclude<R, Layer.Success<Layers[number]>> > <A, E, R, ROut, E2, RIn>( self: Effect<A, E, R>, layer: Layer.Layer<ROut, E2, RIn>, options?: { readonly local?: boolean | undefined } | undefined ): Effect<A, E | E2, RIn | Exclude<R, ROut>> <A, E, R, R2>(self: Effect<A, E, R>, context: Context.Context<R2>): Effect<A, E, Exclude<R, R2>>}Since v2.0.0
provideContext
Section titled “provideContext”Provides a context to an effect, fulfilling its service requirements.
Details
This function provides multiple services at once by supplying a context that contains all the required services. It removes the provided services from the effect’s requirements, making them available to the effect.
Example (Providing a complete context)
import { Context, Effect } from "effect"
// Define service keysconst Logger = Context.Service<{ log: (msg: string) => void}>("Logger")const Database = Context.Service<{ query: (sql: string) => string}>("Database")
// Create a context with multiple servicesconst context = Context.make(Logger, { log: console.log }).pipe(Context.add(Database, { query: () => "result" }))
// An effect that requires both servicesconst program = Effect.gen(function* () { const logger = yield* Effect.service(Logger) const db = yield* Effect.service(Database) logger.log("Querying database") return db.query("SELECT * FROM users")})
const provided = Effect.provideContext(program, context)Signature
declare const provideContext: { <XR>(context: Context.Context<XR>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, XR>> <A, E, R, XR>(self: Effect<A, E, R>, context: Context.Context<XR>): Effect<A, E, Exclude<R, XR>>}Since v4.0.0
error accumulation
Section titled “error accumulation”validate
Section titled “validate”Applies an effectful function to each element and accumulates all failures.
Details
This function always evaluates every element. If at least one effect fails, all failures are returned as a non-empty array and successes are discarded. If all effects succeed, it returns all collected successes.
Use discard: true to ignore successful values while still validating all
elements.
Example (Validating every element)
import { Effect } from "effect"
const program = Effect.validate([0, 1, 2, 3], (n) => (n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)))
Effect.runPromiseExit(program).then(console.log)// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// reasons: [// { _id: 'Reason', _tag: 'Fail', error: '0 is even' },// { _id: 'Reason', _tag: 'Fail', error: '2 is even' }// ]// }// }Signature
declare const validate: { <A, B, E, R>( f: (a: A, i: number) => Effect<B, E, R>, options?: { readonly concurrency?: Concurrency | undefined; readonly discard?: false | undefined } | undefined ): (elements: Iterable<A>) => Effect<Array<B>, Arr.NonEmptyArray<E>, R> <A, B, E, R>( f: (a: A, i: number) => Effect<B, E, R>, options: { readonly concurrency?: Concurrency | undefined; readonly discard: true } ): (elements: Iterable<A>) => Effect<void, Arr.NonEmptyArray<E>, R> <A, B, E, R>( elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options?: { readonly concurrency?: Concurrency | undefined; readonly discard?: false | undefined } | undefined ): Effect<Array<B>, Arr.NonEmptyArray<E>, R> <A, B, E, R>( elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options: { readonly concurrency?: Concurrency | undefined; readonly discard: true } ): Effect<void, Arr.NonEmptyArray<E>, R>}Since v2.0.0
error handling
Section titled “error handling”TagsWithReason (type alias)
Section titled “TagsWithReason (type alias)”Type helper that keeps only error tags whose tagged error contains a tagged reason field.
When to use
Use to constrain custom helpers or overloads to parent error tags whose error contains a tagged reason.
Details
The mapped type keeps each parent error tag whose extracted tagged error has at least one reason tag, and removes tags that do not carry tagged reasons.
See
unwrapReasonfor promoting nested reason errors into the error channelcatchReasonfor handling one nested reason tagcatchReasonsfor handling several nested reason tags
Signature
type TagsWithReason<E> = { [T in Tags<E>]: ReasonTags<ExtractTag<E, T>> extends never ? never : T}[Tags<E>]Since v4.0.0
Handles all errors in an effect by providing a fallback effect.
When to use
Use when every recoverable error from an effect should be handled by the same fallback function while unrecoverable defects remain defects.
Details
The catch function catches any errors that may occur during the
execution of an effect and allows you to handle them by specifying a fallback
effect. This ensures that the program continues without failing by recovering
from errors using the provided fallback logic.
Gotchas
catch only handles recoverable errors. It will not recover from
unrecoverable defects.
See
catchCausefor a version that can recover from both recoverable and unrecoverable errors.
Signature
declare const catch: { <E, A2, E2, R2>(f: (e: E) => Effect<A2, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2, R2 | R>; <A, E, R, A2, E2, R2>(self: Effect<A, E, R>, f: (e: E) => Effect<A2, E2, R2>): Effect<A2 | A, E2, R2 | R>; }Since v4.0.0
catchCause
Section titled “catchCause”Handles both recoverable and unrecoverable errors by providing a recovery effect.
When to use
Use when you need to recover from an Effect by inspecting the full Cause,
including recoverable failures, defects, and interruptions, instead of only
the typed error value.
Details
When to Recover from Defects:
Defects are unexpected errors that typically shouldn’t be recovered from, as they often indicate serious issues. However, in some cases, such as dynamically loaded plugins, controlled recovery might be needed.
Example (Recovering from full failure causes)
import { Cause, Console, Effect } from "effect"
// An effect that might fail in different waysconst program = Effect.die("Something went wrong")
// Recover from any cause (including defects)const recovered = Effect.catchCause(program, (cause) => { if (Cause.hasDies(cause)) { return Console.log("Caught defect").pipe(Effect.as("Recovered from defect")) } return Effect.succeed("Unknown error")})Signature
declare const catchCause: { <E, A2, E2, R2>( f: (cause: Cause.Cause<E>) => Effect<A2, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2, R2 | R> <A, E, R, A2, E2, R2>( self: Effect<A, E, R>, f: (cause: Cause.Cause<E>) => Effect<A2, E2, R2> ): Effect<A | A2, E2, R | R2>}Since v4.0.0
catchCauseFilter
Section titled “catchCauseFilter”Recovers from specific failures based on a Filter.
When to use
Use when you need to recover an Effect only from causes selected by a
Filter, while giving the recovery both the selected value and the original
Cause.
Details
The filter is applied to the full Cause. When it succeeds, the handler
receives the selected value and the original cause. When it fails, the effect
re-fails with the residual cause returned by the filter.
See
catchCauseIffor predicate-based cause selectioncatchFilterfor filtering typed error values instead of full causescatchCausefor recovering from every cause without filtering
Signature
declare const catchCauseFilter: { <E, B, E2, R2, EB, X extends Cause.Cause<any>>( filter: Filter.Filter<Cause.Cause<E>, EB, X>, f: (failure: EB, cause: Cause.Cause<E>) => Effect<B, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A | B, Cause.Cause.Error<X> | E2, R | R2> <A, E, R, B, E2, R2, EB, X extends Cause.Cause<any>>( self: Effect<A, E, R>, filter: Filter.Filter<Cause.Cause<E>, EB, X>, f: (failure: EB, cause: Cause.Cause<E>) => Effect<B, E2, R2> ): Effect<A | B, Cause.Cause.Error<X> | E2, R | R2>}Since v4.0.0
catchCauseIf
Section titled “catchCauseIf”Recovers from specific failures based on a predicate.
When to use
Use to recover an Effect from full causes selected by a predicate.
Details
This function allows you to conditionally catch and recover from failures that match a specific predicate. This is useful when you want to handle only certain types of errors while letting others propagate.
Example (Recovering from selected causes)
import { Cause, Console, Effect } from "effect"
const httpRequest = Effect.fail("Network Error")
// Only catch network-related failuresconst program = Effect.catchCauseIf(httpRequest, Cause.hasFails, (cause) => Effect.gen(function* () { yield* Console.log(`Caught network error: ${Cause.squash(cause)}`) return "Fallback response" }))
Effect.runPromise(program).then(console.log)// Output: "Caught network error: Network Error"// Then: "Fallback response"See
catchCausefor recovering from every causecatchCauseFilterfor selecting full causes with aFiltercatchIffor predicate-based recovery from typed errors
Signature
declare const catchCauseIf: { <E, B, E2, R2>( predicate: Predicate.Predicate<Cause.Cause<E>>, f: (cause: Cause.Cause<E>) => Effect<B, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A | B, E | E2, R | R2> <A, E, R, B, E2, R2>( self: Effect<A, E, R>, predicate: Predicate.Predicate<Cause.Cause<E>>, f: (cause: Cause.Cause<E>) => Effect<B, E2, R2> ): Effect<A | B, E | E2, R | R2>}Since v4.0.0
catchDefect
Section titled “catchDefect”Recovers from defects using a provided recovery function.
When to use
Use when you need to report or translate defects at integration boundaries.
Details
catchDefect handles unexpected defects, such as thrown exceptions or
values passed to die, without catching typed failures or interruptions.
When to Recover from Defects:
Defects are unexpected errors that typically should not be recovered from, as they often indicate serious issues. In some cases, such as dynamically loaded plugins, controlled recovery may be needed.
Example (Recovering from defects)
import { Console, Effect } from "effect"
// An effect that might throw an unexpected error (defect)const program = Effect.sync(() => { throw new Error("Unexpected error")})
// Recover from defects onlyconst recovered = Effect.catchDefect(program, (defect) => { return Console.log(`Caught defect: ${defect}`).pipe(Effect.as("Recovered from defect"))})Signature
declare const catchDefect: { <A2, E2, R2>( f: (defect: unknown) => Effect<A2, E2, R2> ): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2 | E, R2 | R> <A, E, R, A2, E2, R2>( self: Effect<A, E, R>, f: (defect: unknown) => Effect<A2, E2, R2> ): Effect<A | A2, E | E2, R | R2>}Since v4.0.0
catchFilter
Section titled “catchFilter”Recovers from specific errors using a Filter.
When to use
Use to recover from typed Effect errors with a reusable Filter when
matching can also narrow or transform the error before choosing the recovery
effect.
Details
The filter runs on typed failures extracted from the Cause. Successful
filter results are passed to f; failed filter results are passed to
orElse when provided. Without orElse, the original failure cause is
preserved.
See
catchIffor predicate-based recovery from typed errorscatchTagfor recovering from a single tagged errorcatchTagsfor recovering from several tagged errorscatchCauseFilterfor filtering full causes instead of typed errors
Signature
declare const catchFilter: { <E, EB, A2, E2, R2, X, A3 = unassigned, E3 = never, R3 = never>( filter: Filter.Filter<NoInfer<E>, EB, X>, f: (e: EB) => Effect<A2, E2, R2>, orElse?: ((e: X) => Effect<A3, E3, R3>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect<A | A2 | Exclude<A3, unassigned>, E2 | E3 | (A3 extends unassigned ? X : never), R | R2 | R3> <A, E, R, EB, A2, E2, R2, X, A3 = unassigned, E3 = never, R3 = never>( self: Effect<A, E, R>, filter: Filter.Filter<NoInfer<E>, EB, X>, f: (e: EB) => Effect<A2, E2, R2>, orElse?: ((e: X) => Effect<A3, E3, R3>) | undefined ): Effect<A | A2 | Exclude<A3, unassigned>, E2 | E3 | (A3 extends unassigned ? X : never), R | R2 | R3>}Since v4.0.0
catchIf
Section titled “catchIf”Recovers from specific errors using a Predicate or Refinement.
When to use
Use when you need to recover from errors that match a condition.
Details
Use a Refinement for type narrowing or a Predicate for simple boolean
matching. Non-matching errors re-fail with the original cause. Defects and
interrupts are not caught.
Example (Recovering when a predicate matches)
import { Data, Effect, Filter } from "effect"
class NotFound extends Data.TaggedError("NotFound")<{ id: string }> {}
const program = Effect.fail(new NotFound({ id: "user-1" }))
// With a refinementconst recovered = program.pipe( Effect.catchIf( (error): error is NotFound => error._tag === "NotFound", (error) => Effect.succeed(`missing:${error.id}`) ))
// With a Filterconst recovered2 = program.pipe( Effect.catchFilter(Filter.tagged("NotFound"), (error) => Effect.succeed(`missing:${error.id}`)))Signature
declare const catchIf: { <E, EB extends E, A2, E2, R2, A3 = unassigned, E3 = never, R3 = never>( refinement: Predicate.Refinement<NoInfer<E>, EB>, f: (e: EB) => Effect<A2, E2, R2>, orElse?: ((e: Exclude<E, EB>) => Effect<A3, E3, R3>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect<A | A2 | Exclude<A3, unassigned>, E2 | E3 | (A3 extends unassigned ? Exclude<E, EB> : never), R | R2 | R3> <E, A2, E2, R2, A3 = unassigned, E3 = never, R3 = never>( predicate: Predicate.Predicate<NoInfer<E>>, f: (e: NoInfer<E>) => Effect<A2, E2, R2>, orElse?: ((e: NoInfer<E>) => Effect<A3, E3, R3>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect<A | A2 | Exclude<A3, unassigned>, E2 | E3 | (A3 extends unassigned ? E : never), R | R2 | R3> <A, E, R, EB extends E, A2, E2, R2, A3 = unassigned, E3 = never, R3 = never>( self: Effect<A, E, R>, refinement: Predicate.Refinement<E, EB>, f: (e: EB) => Effect<A2, E2, R2>, orElse?: ((e: Exclude<E, EB>) => Effect<A3, E3, R3>) | undefined ): Effect<A | A2 | Exclude<A3, unassigned>, E2 | E3 | (A3 extends unassigned ? Exclude<E, EB> : never), R | R2 | R3> <A, E, R, A2, E2, R2, A3 = unassigned, E3 = never, R3 = never>( self: Effect<A, E, R>, predicate: Predicate.Predicate<E>, f: (e: E) => Effect<A2, E2, R2>, orElse?: ((e: E) => Effect<A3, E3, R3>) | undefined ): Effect<A | A2 | Exclude<A3, unassigned>, E2 | E3 | (A3 extends unassigned ? E : never), R | R2 | R3>}Since v2.0.0
catchNoSuchElement
Section titled “catchNoSuchElement”Catches NoSuchElementError failures and converts them to Option.none.
When to use
Use when you expect missing-value failures and want them to become an optional success while all other failures keep failing.
Details
Success values become Option.some, NoSuchElementError becomes
Option.none, and all other errors are preserved.
Example (Recovering from missing Option values)
import { Effect, Option } from "effect"
const some = Effect.fromNullishOr(1).pipe(Effect.catchNoSuchElement)const none = Effect.fromNullishOr(null).pipe(Effect.catchNoSuchElement)
Effect.runPromise(some).then(console.log) // { _id: 'Option', _tag: 'Some', value: 1 }Effect.runPromise(none).then(console.log) // { _id: 'Option', _tag: 'None' }See
fromOptionfor convertingOption.noneintoNoSuchElementErrorfromNullishOrfor converting nullish values intoNoSuchElementErroroptionfor converting any failure intoOption.none
Signature
declare const catchNoSuchElement: <A, E, R>( self: Effect<A, E, R>) => Effect<Option<A>, Exclude<E, Cause.NoSuchElementError>, R>Since v4.0.0
catchReason
Section titled “catchReason”Catches a specific reason within a tagged error.
When to use
Use to handle one nested reason inside an Effect’s tagged error while
preserving the parent error shape for unmatched reasons.
Details
Use this to handle nested error causes without removing the parent error from the error channel. The handler receives the unwrapped reason.
Example (Handling an error reason)
import { Data, Effect } from "effect"
class RateLimitError extends Data.TaggedError("RateLimitError")<{ retryAfter: number}> {}
class QuotaExceededError extends Data.TaggedError("QuotaExceededError")<{ limit: number}> {}
class AiError extends Data.TaggedError("AiError")<{ reason: RateLimitError | QuotaExceededError}> {}
declare const program: Effect.Effect<string, AiError>
// Handle rate limits specificallyconst handled = program.pipe( Effect.catchReason("AiError", "RateLimitError", (reason) => Effect.succeed(`Retry after ${reason.retryAfter}s`)))See
catchReasonsfor handling several nested reason tags
Signature
declare const catchReason: { < K extends Tags<E>, E, RK extends ReasonTags<ExtractTag<NoInfer<E>, K>>, A2, E2, R2, A3 = unassigned, E3 = never, R3 = never >( errorTag: K, reasonTag: RK, f: ( reason: ExtractReason<ExtractTag<NoInfer<E>, K>, RK>, error: NarrowReason<ExtractTag<NoInfer<E>, K>, RK> ) => Effect<A2, E2, R2>, orElse?: | (( reasons: ExcludeReason<ExtractTag<NoInfer<E>, K>, RK>, error: OmitReason<ExtractTag<NoInfer<E>, K>, RK> ) => Effect<A3, E3, R3>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect< A | A2 | Exclude<A3, unassigned>, ExcludeTag<E, K> | E2 | E3 | (A3 extends unassigned ? ExtractTag<E, K> : never), R | R2 | R3 > < A, E, R, K extends Tags<E>, RK extends ReasonTags<ExtractTag<E, K>>, A2, E2, R2, A3 = unassigned, E3 = never, R3 = never >( self: Effect<A, E, R>, errorTag: K, reasonTag: RK, f: (reason: ExtractReason<ExtractTag<E, K>, RK>, error: NarrowReason<ExtractTag<E, K>, RK>) => Effect<A2, E2, R2>, orElse?: | ((reasons: ExcludeReason<ExtractTag<E, K>, RK>, error: OmitReason<ExtractTag<E, K>, RK>) => Effect<A3, E3, R3>) | undefined ): Effect< A | A2 | Exclude<A3, unassigned>, ExcludeTag<E, K> | E2 | E3 | (A3 extends unassigned ? ExtractTag<E, K> : never), R | R2 | R3 >}Since v4.0.0
catchReasons
Section titled “catchReasons”Catches multiple reasons within a tagged error using an object of handlers.
Example (Handling multiple error reasons)
import { Data, Effect } from "effect"
class RateLimitError extends Data.TaggedError("RateLimitError")<{ retryAfter: number}> {}
class QuotaExceededError extends Data.TaggedError("QuotaExceededError")<{ limit: number}> {}
class AiError extends Data.TaggedError("AiError")<{ reason: RateLimitError | QuotaExceededError}> {}
declare const program: Effect.Effect<string, AiError>
const handled = program.pipe( Effect.catchReasons("AiError", { RateLimitError: (reason) => Effect.succeed(`Retry after ${reason.retryAfter}s`), QuotaExceededError: (reason) => Effect.succeed(`Quota exceeded: ${reason.limit}`) }))Signature
declare const catchReasons: { < K extends Tags<E>, E, Cases extends { [RK in ReasonTags<ExtractTag<NoInfer<E>, K>>]+?: ( reason: ExtractReason<ExtractTag<NoInfer<E>, K>, RK>, error: NarrowReason<ExtractTag<NoInfer<E>, K>, RK> ) => Effect<any, any, any> }, A2 = unassigned, E2 = never, R2 = never >( errorTag: K, cases: Cases, orElse?: | (( reason: ExcludeReason<ExtractTag<NoInfer<E>, K>, Extract<keyof Cases, string>>, error: OmitReason<ExtractTag<NoInfer<E>, K>, Extract<keyof Cases, string>> ) => Effect<A2, E2, R2>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect< | A | Exclude<A2, unassigned> | { [RK in keyof Cases]: Cases[RK] extends (...args: Array<any>) => Effect<infer A, any, any> ? A : never }[keyof Cases], | ExcludeTag<E, K> | E2 | (A2 extends unassigned ? ExtractTag<E, K> : never) | { [RK in keyof Cases]: Cases[RK] extends (...args: Array<any>) => Effect<any, infer E, any> ? E : never }[keyof Cases], | R | R2 | { [RK in keyof Cases]: Cases[RK] extends (...args: Array<any>) => Effect<any, any, infer R> ? R : never }[keyof Cases] > < A, E, R, K extends Tags<E>, Cases extends { [RK in ReasonTags<ExtractTag<E, K>>]+?: ( reason: ExtractReason<ExtractTag<E, K>, RK>, error: NarrowReason<ExtractTag<E, K>, RK> ) => Effect<any, any, any> }, A2 = unassigned, E2 = never, R2 = never >( self: Effect<A, E, R>, errorTag: K, cases: Cases, orElse?: | (( reason: ExcludeReason<ExtractTag<NoInfer<E>, K>, Extract<keyof Cases, string>>, error: OmitReason<ExtractTag<NoInfer<E>, K>, Extract<keyof Cases, string>> ) => Effect<A2, E2, R2>) | undefined ): Effect< | A | Exclude<A2, unassigned> | { [RK in keyof Cases]: Cases[RK] extends (...args: Array<any>) => Effect<infer A, any, any> ? A : never }[keyof Cases], | ExcludeTag<E, K> | E2 | (A2 extends unassigned ? ExtractTag<E, K> : never) | { [RK in keyof Cases]: Cases[RK] extends (...args: Array<any>) => Effect<any, infer E, any> ? E : never }[keyof Cases], | R | R2 | { [RK in keyof Cases]: Cases[RK] extends (...args: Array<any>) => Effect<any, any, infer R> ? R : never }[keyof Cases] >}Since v4.0.0
catchTag
Section titled “catchTag”Catches and handles specific errors by their _tag field, which is used as a
discriminator.
When to use
Use when you need to recover from one specific tagged error in an effect error channel.
Details
The error type must have a readonly _tag field. catchTag matches that
field and only handles errors with the requested tag.
Example (Handling a tagged error)
import { Effect } from "effect"
class NetworkError { readonly _tag = "NetworkError" constructor(readonly message: string) {}}
class ValidationError { readonly _tag = "ValidationError" constructor(readonly message: string) {}}
declare const task: Effect.Effect<string, NetworkError | ValidationError>
const program = Effect.catchTag(task, "NetworkError", (error) => Effect.succeed(`Recovered from network error: ${error.message}`))See
catchTagsfor handling multiple tagged errors in one callcatchIffor recovering from errors that match a predicate
Signature
declare const catchTag: { < const K extends Tags<E> | Arr.NonEmptyReadonlyArray<Tags<E>>, E, A1, E1, R1, A2 = unassigned, E2 = never, R2 = never >( k: K, f: (e: ExtractTag<NoInfer<E>, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K>) => Effect<A1, E1, R1>, orElse?: | ((e: ExcludeTag<E, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K>) => Effect<A2, E2, R2>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect< A | A1 | Exclude<A2, unassigned>, | E1 | E2 | (A2 extends unassigned ? ExcludeTag<E, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K> : never), R | R1 | R2 > < A, E, R, const K extends Tags<E> | Arr.NonEmptyReadonlyArray<Tags<E>>, R1, E1, A1, A2 = unassigned, E2 = never, R2 = never >( self: Effect<A, E, R>, k: K, f: (e: ExtractTag<E, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K>) => Effect<A1, E1, R1>, orElse?: | ((e: ExcludeTag<E, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K>) => Effect<A2, E2, R2>) | undefined ): Effect< A | A1 | Exclude<A2, unassigned>, | E1 | E2 | (A2 extends unassigned ? ExcludeTag<E, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K> : never), R | R1 | R2 >}Since v2.0.0
catchTags
Section titled “catchTags”Handles multiple errors in a single block of code using their _tag field.
When to use
Use when one recovery step should handle several tagged error types by
matching their readonly _tag fields.
Details
Pass a handler table whose keys are tags, plus an optional fallback for unmatched errors.
The error type must have a readonly _tag field to use catchTags. This
field is used to identify and match errors.
Example (Handling multiple tagged errors)
import { Data, Effect } from "effect"
// Define tagged error typesclass ValidationError extends Data.TaggedError("ValidationError")<{ message: string}> {}
class NetworkError extends Data.TaggedError("NetworkError")<{ statusCode: number}> {}
// An effect that might fail with multiple error typesdeclare const program: Effect.Effect<string, ValidationError | NetworkError>
// Handle multiple error types at onceconst handled = Effect.catchTags(program, { ValidationError: (error) => Effect.succeed(`Validation failed: ${error.message}`), NetworkError: (error) => Effect.succeed(`Network error: ${error.statusCode}`)})Signature
declare const catchTags: { < E, Cases extends { [K in Extract<E, { _tag: string }>["_tag"]]+?: (error: Extract<E, { _tag: K }>) => Effect<any, any, any> } & (unknown extends E ? {} : { [K in Exclude<keyof Cases, Extract<E, { _tag: string }>["_tag"]>]: never }), A2 = unassigned, E2 = never, R2 = never >( cases: Cases, orElse?: ((e: Exclude<E, { _tag: keyof Cases }>) => Effect<A2, E2, R2>) | undefined ): <A, R>( self: Effect<A, E, R> ) => Effect< | A | Exclude<A2, unassigned> | { [K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<infer A, any, any> ? A : never }[keyof Cases], | E2 | (A2 extends unassigned ? Exclude<E, { _tag: keyof Cases }> : never) | { [K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, infer E, any> ? E : never }[keyof Cases], | R | R2 | { [K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, any, infer R> ? R : never }[keyof Cases] > < R, E, A, Cases extends { [K in Extract<E, { _tag: string }>["_tag"]]+?: (error: Extract<E, { _tag: K }>) => Effect<any, any, any> } & (unknown extends E ? {} : { [K in Exclude<keyof Cases, Extract<E, { _tag: string }>["_tag"]>]: never }), A2 = unassigned, E2 = never, R2 = never >( self: Effect<A, E, R>, cases: Cases, orElse?: ((e: Exclude<E, { _tag: keyof Cases }>) => Effect<A2, E2, R2>) | undefined ): Effect< | A | Exclude<A2, unassigned> | { [K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<infer A, any, any> ? A : never }[keyof Cases], | E2 | (A2 extends unassigned ? Exclude<E, { _tag: keyof Cases }> : never) | { [K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, infer E, any> ? E : never }[keyof Cases], | R | R2 | { [K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, any, infer R> ? R : never }[keyof Cases] >}Since v2.0.0
ignore
Section titled “ignore”Discards both the success and failure values of an effect.
When to use
Use when an effect should run for its side effects while both success and failure values are discarded.
Details
Use the log option to emit the full Cause when the effect fails,
and message to prepend a custom log message.
Example (Discarding success and failure values)
import { Effect } from "effect"
// ┌─── Effect<number, string, never>// ▼const task = Effect.fail("Uh oh!").pipe(Effect.as(5))
// ┌─── Effect<void, never, never>// ▼const program = task.pipe(Effect.ignore)Example (Logging failures while ignoring results)
import { Effect } from "effect"
const task = Effect.fail("Uh oh!")
const program = task.pipe(Effect.ignore({ log: true }))const programWarn = task.pipe(Effect.ignore({ log: "Warn", message: "Ignoring task failure" }))Signature
declare const ignore: < Arg extends | Effect<any, any, any> | { readonly log?: boolean | Severity | undefined; readonly message?: string | undefined } | undefined = { readonly log?: boolean | Severity | undefined; readonly message?: string | undefined }>( effectOrOptions?: Arg, options?: { readonly log?: boolean | Severity | undefined; readonly message?: string | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Effect<void, never, _R> : <A, E, R>(self: Effect<A, E, R>) => Effect<void, never, R>Since v2.0.0
ignoreCause
Section titled “ignoreCause”Ignores the effect’s failure cause, including defects and interruptions.
When to use
Use when a best-effort effect should never fail, even from defects or interruption, and optional cause logging is enough.
Details
Use the log option to emit the full Cause when the effect fails,
and message to prepend a custom log message.
Example (Ignoring failures and logging causes)
import { Effect } from "effect"
const task = Effect.fail("boom")
const program = task.pipe(Effect.ignoreCause)const programLog = task.pipe(Effect.ignoreCause({ log: true, message: "Ignoring failure cause" }))Signature
declare const ignoreCause: < Arg extends | Effect<any, any, any> | { readonly log?: boolean | Severity | undefined; readonly message?: string | undefined } | undefined = { readonly log?: boolean | Severity | undefined; readonly message?: string | undefined }>( effectOrOptions?: Arg, options?: { readonly log?: boolean | Severity | undefined; readonly message?: string | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Effect<void, never, _R> : <A, E, R>(self: Effect<A, E, R>) => Effect<void, never, R>Since v4.0.0
mapError
Section titled “mapError”Transforms the failure value of an effect without changing its success value.
When to use
Use to translate an Effect’s typed failures while leaving successful values
unchanged.
Details
Only the failure channel is transformed. The success channel and requirements are preserved.
Example (Transforming the error channel)
import { Data, Effect } from "effect"
class TaskError extends Data.TaggedError("TaskError")<{ readonly message: string }> {}
// ┌─── Effect<number, string, never>// ▼const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
// ┌─── Effect<number, TaskError, never>// ▼const mapped = Effect.mapError(simulatedTask, (message) => new TaskError({ message }))See
mapfor a version that operates on the success channel.mapBothfor a version that operates on both channels.
Signature
declare const mapError: { <E, E2>(f: (e: E) => E2): <A, R>(self: Effect<A, E, R>) => Effect<A, E2, R> <A, E, R, E2>(self: Effect<A, E, R>, f: (e: E) => E2): Effect<A, E2, R>}Since v2.0.0
Retries typed failures from an effect according to a retry policy.
When to use
Use when you need to rerun an effect after transient typed failures, such as network issues or temporary resource unavailability.
Details
The policy can be a Schedule, a schedule builder, or a Retry.Options
object using schedule, times, while, or until. If a retry eventually
succeeds, the returned effect succeeds with that value. If the policy stops
while the effect is still failing, the last failure is propagated.
Gotchas
The source effect is always evaluated once before any retry policy is
applied. For example, Schedule.recurs(3) allows up to three retries after
the initial attempt.
Defects and interruptions are not retried.
Example (Retrying with a schedule)
import { Data, Effect, Schedule } from "effect"
class AttemptError extends Data.TaggedError("AttemptError")<{ readonly attempt: number }> {}
let attempt = 0const task = Effect.callback<string, AttemptError>((resume) => { attempt++ if (attempt <= 2) { resume(Effect.fail(new AttemptError({ attempt }))) } else { resume(Effect.succeed("Success!")) }})
const policy = Schedule.addDelay(Schedule.recurs(5), () => Effect.succeed("100 millis"))const program = Effect.retry(task, policy)
Effect.runPromise(program).then(console.log)// Output: "Success!" (after 2 retries)See
retryOrElsefor a version that allows you to run a fallback.repeatif your retry condition is based on successful outcomes rather than errors.
Signature
declare const retry: { <E, O extends Retry.Options<E>>(options: O): <A, R>(self: Effect<A, E, R>) => Retry.Return<R, E, A, O> <B, E, Error, Env>( policy: Schedule<B, NoInfer<E>, Error, Env> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | Error, R | Env> <B, E, Error, Env>( builder: ( $: <O, SE, R>(_: Schedule<O, NoInfer<E>, SE, R>) => Schedule<O, E, SE, R> ) => Schedule<B, NoInfer<E>, Error, Env> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | Error, R | Env> <A, E, R, O extends Retry.Options<E>>(self: Effect<A, E, R>, options: O): Retry.Return<R, E, A, O> <A, E, R, B, Error, Env>( self: Effect<A, E, R>, policy: Schedule<B, NoInfer<E>, Error, Env> ): Effect<A, E | Error, R | Env> <A, E, R, B, Error, Env>( self: Effect<A, E, R>, builder: ( $: <O, SE, R>(_: Schedule<O, NoInfer<E>, SE, R>) => Schedule<O, E, SE, R> ) => Schedule<B, NoInfer<E>, Error, Env> ): Effect<A, E | Error, R | Env>}Since v2.0.0
retryOrElse
Section titled “retryOrElse”Retries a failing effect and runs a fallback effect if retries are exhausted.
When to use
Use when you want to handle failures gracefully by specifying an alternative action after repeated failures.
Details
The Effect.retryOrElse function attempts to retry a failing effect multiple
times according to a defined Schedule policy.
If the retries are exhausted and the effect still fails, it runs a fallback effect instead.
Example (Falling back after retries are exhausted)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkTimeoutError extends Data.TaggedError("NetworkTimeoutError")<{}> {}
let attempt = 0const networkRequest = Effect.gen(function* () { attempt++ yield* Console.log(`Network attempt ${attempt}`) if (attempt < 3) { return yield* Effect.fail(new NetworkTimeoutError()) } return "Network data"})
// Retry up to 2 times, then fall back to cached dataconst program = Effect.retryOrElse(networkRequest, Schedule.recurs(2), (error, retryCount) => Effect.gen(function* () { yield* Console.log(`All ${retryCount} retries failed, using cache`) return "Cached data" }))
Effect.runPromise(program).then(console.log)// Output:// Network attempt 1// Network attempt 2// Network attempt 3// Network dataSee
retryfor a version that does not run a fallback effect.
Signature
declare const retryOrElse: { <A1, E, E1, R1, A2, E2, R2>( policy: Schedule<A1, NoInfer<E>, E1, R1>, orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A | A2, E1 | E2, R | R1 | R2> <A, E, R, A1, E1, R1, A2, E2, R2>( self: Effect<A, E, R>, policy: Schedule<A1, NoInfer<E>, E1, R1>, orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2> ): Effect<A | A2, E1 | E2, R | R1 | R2>}Since v2.0.0
sandbox
Section titled “sandbox”Exposes an effect’s full failure cause in the error channel as Cause<E>.
Details
Use sandbox when downstream error handling needs to distinguish typed
failures, defects, and interruptions. Use unsandbox to restore the original
typed error channel after cause-level handling.
Example (Exposing failures as causes)
import { Cause, Effect } from "effect"
const task = Effect.fail("Something went wrong")
// Sandbox exposes the full cause as the error typeconst program = Effect.gen(function* () { const result = yield* Effect.flip(Effect.sandbox(task)) return `Caught cause: ${Cause.squash(result)}`})
Effect.runPromise(program).then(console.log)// Output: "Caught cause: Something went wrong"Signature
declare const sandbox: <A, E, R>(self: Effect<A, E, R>) => Effect<A, Cause.Cause<E>, R>Since v2.0.0
unwrapReason
Section titled “unwrapReason”Promotes nested reason errors into the Effect error channel, replacing the parent error.
Example (Extracting the reason from a tagged error)
import { Data, Effect } from "effect"
class RateLimitError extends Data.TaggedError("RateLimitError")<{ retryAfter: number}> {}
class QuotaExceededError extends Data.TaggedError("QuotaExceededError")<{ limit: number}> {}
class AiError extends Data.TaggedError("AiError")<{ reason: RateLimitError | QuotaExceededError}> {}
declare const program: Effect.Effect<string, AiError>
// Before: Effect<string, AiError>// After: Effect<string, RateLimitError | QuotaExceededError>const unwrapped = program.pipe(Effect.unwrapReason("AiError"))Signature
declare const unwrapReason: { <K extends TagsWithReason<E>, E>( errorTag: K ): <A, R>(self: Effect<A, E, R>) => Effect<A, ExcludeTag<E, K> | ReasonOf<ExtractTag<E, K>>, R> <A, E, R, K extends TagsWithReason<E>>( self: Effect<A, E, R>, errorTag: K ): Effect<A, ExcludeTag<E, K> | ReasonOf<ExtractTag<E, K>>, R>}Since v4.0.0
withErrorReporting
Section titled “withErrorReporting”Runs an effect and reports any errors to the configured ErrorReporters.
Details
If the defectsOnly option is set to true, only defects (unrecoverable
errors) will be reported, while regular failures will be ignored.
Signature
declare const withErrorReporting: < Arg extends Effect<any, any, any> | { readonly defectsOnly?: boolean | undefined } | undefined = { readonly defectsOnly?: boolean | undefined }>( effectOrOptions: Arg, options?: { readonly defectsOnly?: boolean | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Arg : <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Since v4.0.0
fallback
Section titled “fallback”firstSuccessOf
Section titled “firstSuccessOf”Runs a sequence of effects and returns the result of the first successful one.
When to use
Use when you have prioritized fallback Effects, such as attempting
multiple APIs, reading configuration from several sources, or trying
alternative resource locations in order.
Details
This function executes the provided effects in sequence, stopping at the first success. If an effect succeeds, its result is returned immediately and no further effects in the sequence are executed.
If all effects fail, the returned effect fails with the error from the last
effect. If the collection is empty, the returned effect defects with an
Error whose message is "Received an empty collection of effects".
Example (Trying alternatives until one succeeds)
import { Effect } from "effect"
const primary = Effect.fail("primary unavailable")const secondary = Effect.succeed("secondary result")const tertiary = Effect.sync(() => { throw new Error("not evaluated")})
const program = Effect.firstSuccessOf([primary, secondary, tertiary])
console.log(Effect.runSync(program))// Output: "secondary result"Signature
declare const firstSuccessOf: <Eff extends Effect<any, any, any>>( effects: Iterable<Eff>) => Effect<Success<Eff>, Error<Eff>, Services<Eff>>Since v2.0.0
orElseSucceed
Section titled “orElseSucceed”Recovers from a typed failure by producing a fallback success value.
Details
If the source effect succeeds, its value is preserved. If it fails in the
error channel, orElseSucceed evaluates the fallback and succeeds with that
value, removing the typed error from the returned effect.
Defects and interruptions are not recovered by this operator.
Example (Replacing failures with a value)
import { Effect } from "effect"
const validate = (age: number): Effect.Effect<number, string> => { if (age < 0) { return Effect.fail("NegativeAgeError") } else if (age < 18) { return Effect.fail("IllegalAgeError") } else { return Effect.succeed(age) }}
const program = Effect.orElseSucceed(validate(-1), () => 18)
console.log(Effect.runSyncExit(program))// Output:// { _id: 'Exit', _tag: 'Success', value: 18 }Signature
declare const orElseSucceed: { <A2>(evaluate: LazyArg<A2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, never, R> <A, E, R, A2>(self: Effect<A, E, R>, evaluate: LazyArg<A2>): Effect<A | A2, never, R>}Since v2.0.0
withExecutionPlan
Section titled “withExecutionPlan”Applies an ExecutionPlan to an effect, retrying with step-provided resources
until it succeeds or the plan is exhausted.
Details
Each attempt updates ExecutionPlan.CurrentMetadata (attempt and step index),
and retry timing is derived per step (the first attempt uses the remaining
attempts schedule; later retries apply the step schedule at least once).
Example (Retrying with an execution plan)
import { Context, Effect, ExecutionPlan, Layer } from "effect"
const Endpoint = Context.Service<{ url: string }>("Endpoint")
const fetchUrl = Effect.gen(function* () { const endpoint = yield* Effect.service(Endpoint) if (endpoint.url === "bad") { return yield* Effect.fail("Unavailable") } return endpoint.url})
const plan = ExecutionPlan.make( { provide: Layer.succeed(Endpoint, { url: "bad" }), attempts: 2 }, { provide: Layer.succeed(Endpoint, { url: "good" }) })
const program = Effect.withExecutionPlan(fetchUrl, plan)Signature
declare const withExecutionPlan: { <Input, Provides, PlanE, PlanR>( plan: ExecutionPlan<{ provides: Provides; input: Input; error: PlanE; requirements: PlanR }> ): <A, E extends Input, R>(effect: Effect<A, E, R>) => Effect<A, E | PlanE, Exclude<R, Provides> | PlanR> <A, E extends Input, R, Provides, Input, PlanE, PlanR>( effect: Effect<A, E, R>, plan: ExecutionPlan<{ provides: Provides; input: Input; error: PlanE; requirements: PlanR }> ): Effect<A, E | PlanE, Exclude<R, Provides> | PlanR>}Since v3.16.0
filtering
Section titled “filtering”filter
Section titled “filter”Filters elements of an iterable using a predicate, refinement, or effectful predicate.
Example (Filtering success values)
import { Effect } from "effect"
// Sync predicateconst evens = Effect.filter([1, 2, 3, 4], (n) => n % 2 === 0)
// Effectful predicateconst checked = Effect.filter([1, 2, 3], (n) => Effect.succeed(n > 1))
// Use Effect.filterMapEffect for effectful Filter.Filter callbacksSignature
declare const filter: { <A, B extends A>(refinement: Predicate.Refinement<NoInfer<A>, B>): (elements: Iterable<A>) => Effect<Array<B>> <A>(predicate: Predicate.Predicate<NoInfer<A>>): (elements: Iterable<A>) => Effect<Array<A>> <A, E, R>( predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>, options?: { readonly concurrency?: Concurrency | undefined } ): (iterable: Iterable<A>) => Effect<Array<A>, E, R> <A, B extends A>(elements: Iterable<A>, refinement: Predicate.Refinement<A, B>): Effect<Array<B>> <A>(elements: Iterable<A>, predicate: Predicate.Predicate<A>): Effect<Array<A>> <A, E, R>( iterable: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>, options?: { readonly concurrency?: Concurrency | undefined } ): Effect<Array<A>, E, R>}Since v2.0.0
filterMap
Section titled “filterMap”Filters and maps elements of an iterable with a Filter.
When to use
Use when you need to filter an iterable with a Filter inside an Effect,
collecting each filter success value.
Details
Result.succeed values are collected in the returned array, and
Result.fail values are skipped.
See
filterfor keeping original elements with a boolean predicate, refinement, or effectful predicatefilterMapEffectfor using an effectfulFilter
Signature
declare const filterMap: { <A, B, X>(filter: Filter.Filter<NoInfer<A>, B, X>): (elements: Iterable<A>) => Effect<Array<B>> <A, B, X>(elements: Iterable<A>, filter: Filter.Filter<NoInfer<A>, B, X>): Effect<Array<B>>}Since v2.0.0
filterMapEffect
Section titled “filterMapEffect”Filters and maps elements of an iterable effectfully with a FilterEffect.
When to use
Use when you need to filter each iterable element effectfully and transform accepted elements into successful output values.
Details
Result.succeed values are collected in the returned array, and
Result.fail values are skipped.
Gotchas
With concurrent execution, successful values are collected in completion order, not input order.
See
filterMapfor using a synchronousFilterfilterfor keeping original elements with a predicate
Signature
declare const filterMapEffect: { <A, B, X, E, R>( filter: Filter.FilterEffect<NoInfer<A>, B, X, E, R>, options?: { readonly concurrency?: Concurrency | undefined } ): (elements: Iterable<A>) => Effect<Array<B>, E, R> <A, B, X, E, R>( elements: Iterable<A>, filter: Filter.FilterEffect<NoInfer<A>, B, X, E, R>, options?: { readonly concurrency?: Concurrency | undefined } ): Effect<Array<B>, E, R>}Since v4.0.0
filterMapOrElse
Section titled “filterMapOrElse”Filters an effect with a Filter, providing an alternative effect on failure.
When to use
Use when a successful effect value should be accepted and transformed by a
Filter, while rejected values should continue with an alternative effect
built from the filter failure.
Details
Result.succeed becomes the returned success value, and Result.fail is
passed to orElse.
See
filterOrElsefor using a predicate and fallback effectfilterMapOrFailfor failing the effect when the filter fails
Signature
declare const filterMapOrElse: { <A, B, X, C, E2, R2>( filter: Filter.Filter<NoInfer<A>, B, X>, orElse: (x: X) => Effect<C, E2, R2> ): <E, R>(self: Effect<A, E, R>) => Effect<B | C, E2 | E, R2 | R> <A, E, R, B, X, C, E2, R2>( self: Effect<A, E, R>, filter: Filter.Filter<NoInfer<A>, B, X>, orElse: (x: X) => Effect<C, E2, R2> ): Effect<B | C, E | E2, R | R2>}Since v4.0.0
filterMapOrFail
Section titled “filterMapOrFail”Filters and maps an effect with a Filter, failing when the filter fails.
When to use
Use when validating and transforming one effect success with a synchronous
Filter, while rejected values should fail the effect.
Details
Result.succeed becomes the returned success value. Result.fail is mapped
with orFailWith when provided, or fails with NoSuchElementError.
See
filterMapOrElsefor continuing with a fallback effect when the filter failsfilterOrFailfor validating with a predicate instead of aFilterfilterMapfor filtering and mapping iterable elements
Signature
declare const filterMapOrFail: { <A, B, X, E2>( filter: Filter.Filter<NoInfer<A>, B, X>, orFailWith: (x: X) => E2 ): <E, R>(self: Effect<A, E, R>) => Effect<B, E2 | E, R> <A, B, X>( filter: Filter.Filter<NoInfer<A>, B, X> ): <E, R>(self: Effect<A, E, R>) => Effect<B, Cause.NoSuchElementError | E, R> <A, E, R, B, X, E2>( self: Effect<A, E, R>, filter: Filter.Filter<A, B, X>, orFailWith: (x: X) => E2 ): Effect<B, E2 | E, R> <A, E, R, B, X>(self: Effect<A, E, R>, filter: Filter.Filter<A, B, X>): Effect<B, Cause.NoSuchElementError | E, R>}Since v4.0.0
filterOrElse
Section titled “filterOrElse”Filters an effect, providing an alternative effect if the predicate fails.
When to use
Use when a successful value that fails a predicate should continue with an effectful fallback instead of failing the effect.
Details
This function applies a predicate to the result of an effect. If the
predicate evaluates to false, it executes the orElse effect instead. The
orElse effect can produce an alternative value or perform additional
computations.
Example (Filtering with a fallback effect)
import { Effect } from "effect"
// An effect that produces a numberconst program = Effect.succeed(5)
// Filter for even numbers, provide alternative for odd numbersconst filtered = Effect.filterOrElse( program, (n) => n % 2 === 0, (n) => Effect.succeed(`Number ${n} is odd`))
// Result: "Number 5 is odd" (since 5 is not even)Signature
declare const filterOrElse: { <A, C, E2, R2, B extends A>( refinement: Predicate.Refinement<NoInfer<A>, B>, orElse: (a: EqualsWith<A, B, NoInfer<A>, Exclude<NoInfer<A>, B>>) => Effect<C, E2, R2> ): <E, R>(self: Effect<A, E, R>) => Effect<B | C, E2 | E, R2 | R> <A, C, E2, R2>( predicate: Predicate.Predicate<NoInfer<A>>, orElse: (a: NoInfer<A>) => Effect<C, E2, R2> ): <E, R>(self: Effect<A, E, R>) => Effect<A | C, E2 | E, R2 | R> <A, E, R, C, E2, R2, B extends A>( self: Effect<A, E, R>, refinement: Predicate.Refinement<A, B>, orElse: (a: EqualsWith<A, B, A, Exclude<A, B>>) => Effect<C, E2, R2> ): Effect<B | C, E | E2, R | R2> <A, E, R, C, E2, R2>( self: Effect<A, E, R>, predicate: Predicate.Predicate<NoInfer<A>>, orElse: (a: NoInfer<A>) => Effect<C, E2, R2> ): Effect<A | C, E | E2, R | R2>}Since v2.0.0
filterOrFail
Section titled “filterOrFail”Filters an effect, failing with a custom error if the predicate fails.
Details
This function applies a predicate to the result of an effect. If the
predicate evaluates to false, the effect fails with either a custom
error (if orFailWith is provided) or a NoSuchElementError.
Example (Filtering with a custom failure)
import { Effect } from "effect"
// An effect that produces a numberconst program = Effect.succeed(5)
// Filter for even numbers, fail for odd numbersconst filtered = Effect.filterOrFail( program, (n) => n % 2 === 0, (n) => `Expected even number, got ${n}`)
// Result: Effect.fail("Expected even number, got 5")Signature
declare const filterOrFail: { <A, E2, B extends A>( refinement: Predicate.Refinement<NoInfer<A>, B>, orFailWith: (a: NoInfer<A>) => E2 ): <E, R>(self: Effect<A, E, R>) => Effect<B, E2 | E, R> <A, E2>( predicate: Predicate.Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E2 ): <E, R>(self: Effect<A, E, R>) => Effect<A, E2 | E, R> <A, B extends A>( refinement: Predicate.Refinement<NoInfer<A>, B> ): <E, R>(self: Effect<A, E, R>) => Effect<B, Cause.NoSuchElementError | E, R> <A>( predicate: Predicate.Predicate<NoInfer<A>> ): <E, R>(self: Effect<A, E, R>) => Effect<A, Cause.NoSuchElementError | E, R> <A, E, R, E2, B extends A>( self: Effect<A, E, R>, refinement: Predicate.Refinement<NoInfer<A>, B>, orFailWith: (a: NoInfer<A>) => E2 ): Effect<B, E2 | E, R> <A, E, R, E2>( self: Effect<A, E, R>, predicate: Predicate.Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E2 ): Effect<A, E2 | E, R> <A, E, R, B extends A>( self: Effect<A, E, R>, refinement: Predicate.Refinement<NoInfer<A>, B> ): Effect<B, E | Cause.NoSuchElementError, R> <A, E, R>( self: Effect<A, E, R>, predicate: Predicate.Predicate<NoInfer<A>> ): Effect<A, E | Cause.NoSuchElementError, R>}Since v2.0.0
functions
Section titled “functions”Creates a reusable traced function from an Effect body.
When to use
Use when you are defining a reusable Effect function whose implementation
would otherwise be a normal function returning gen, and you want
tracing spans or stack-frame capture.
Details
Compared to a plain function that returns gen, Effect.fn reuses the
generator body instead of allocating a fresh generator closure around the
arguments on every call. Call Effect.fn(body, ...) for a generic
stack-frame boundary without creating a span. Call
Effect.fn("operationName", options?)(body, ...) when that boundary should
have a readable operation name and the returned Effect should create a
tracing span when run. SpanOptionsNoTrace configures span metadata
such as attributes, links, parent or root selection, kind, sampling, and log
level. Additional arguments after the generator body act like pipe
transforms: each transform receives the previous result and the original
function arguments. When those transforms return an Effect, the returned
effect includes stack-frame metadata and, for the named form, a tracing span.
Generator bodies may declare a this parameter; pass { self } before the
body to bind this when the function is created.
Example (Defining traced effect functions)
import { Effect } from "effect"
const f = Effect.fn("calculateLength")(function* (value: string) { return yield* Effect.succeed(value.length)})
// ┌─── Effect.Effect<number>// ▼const program = f("hello")Example (Transforming the returned Effect)
import { Effect } from "effect"
const f = Effect.fn("formatLength")( function* (value: string) { return yield* Effect.succeed(value.length) }, (effect, value) => effect.pipe(Effect.map((length) => `${value}: ${length}`)))
// ┌─── Effect.Effect<string>// ▼const program = f("hello")Example (Binding this)
import { Effect } from "effect"
class Counter { count = 0
increment = Effect.fn("Counter.increment")({ self: this }, function* (this: Counter, by: number) { this.count += by return yield* Effect.succeed(this.count) })}
const counter = new Counter()
// ┌─── Effect.Effect<number>// ▼const program = counter.increment(1)Example (Annotating a traced non-parametric function)
import { Effect } from "effect"
const f = Effect.fn("calculateLength")(function* (value: string): Effect.fn.Return<number> { return yield* Effect.succeed(value.length)})
// ┌─── Effect.Effect<number>// ▼const program = f("hello")Example (Annotating a traced parametric function)
import { Effect } from "effect"
const f = Effect.fn("succeed")(function* <A>(value: A): Effect.fn.Return<A> { return yield* Effect.succeed(value)})
// ┌─── Effect.Effect<string>// ▼const program = f("hello")Signature
declare const fn: fn.Traced & ((name: string, options?: SpanOptionsNoTrace) => fn.Traced)Since v3.11.0
fnUntraced
Section titled “fnUntraced”Creates an Effect-returning function without tracing.
When to use
Use when you are defining a reusable Effect function whose implementation
would otherwise be a normal function returning gen, especially when
tracing spans or stack-frame capture are not needed.
Details
Compared to a plain function that returns gen, Effect.fnUntraced
reuses the generator body instead of allocating a fresh generator closure
around the arguments on every call. It does not record an Effect stack-frame
boundary and does not create tracing spans. Use fn when you need
those stack frames or spans. Additional arguments after the generator body
act like pipe transforms: each transform receives the previous result and
the original function arguments. Annotate the generator return type with
Effect.fn.Return<A, E, R> when the produced Effect type needs to be
stated explicitly.
Example (Defining untraced effect functions)
import { Effect } from "effect"
const f = Effect.fnUntraced(function* (value: string) { return yield* Effect.succeed(value.length)})
// ┌─── Effect.Effect<number>// ▼const program = f("hello")Example (Transforming the returned Effect)
import { Effect } from "effect"
const f = Effect.fnUntraced( function* (value: string) { return yield* Effect.succeed(value.length) }, (effect, value) => effect.pipe(Effect.map((length) => `${value}: ${length}`)))
// ┌─── Effect.Effect<string>// ▼const program = f("hello")Example (Annotating an untraced non-parametric function)
import { Effect } from "effect"
const f = Effect.fnUntraced(function* (value: string): Effect.fn.Return<number> { return yield* Effect.succeed(value.length)})
// ┌─── Effect.Effect<number>// ▼const program = f("hello")Example (Annotating an untraced parametric function)
import { Effect } from "effect"
const f = Effect.fnUntraced(function* <A>(value: A): Effect.fn.Return<A> { return yield* Effect.succeed(value)})
// ┌─── Effect.Effect<string>// ▼const program = f("hello")Signature
declare const fnUntraced: fn.UntracedSince v3.12.0
guards
Section titled “guards”isEffect
Section titled “isEffect”Checks whether a value is an Effect.
Example (Checking whether a value is an Effect)
import { Effect } from "effect"
console.log(Effect.isEffect(Effect.succeed(1))) // trueconsole.log(Effect.isEffect("hello")) // falseSignature
declare const isEffect: (u: unknown) => u is Effect<any, any, any>Since v2.0.0
interruption
Section titled “interruption”abortSignal
Section titled “abortSignal”Creates an AbortSignal that is managed by the provided scope.
When to use
Use to obtain a scope-managed AbortSignal for APIs that accept cancellation
through a signal.
Details
Each acquisition creates a fresh AbortController. Closing the owning scope
runs a finalizer that aborts the controller and the effect succeeds with the
controller’s signal.
Gotchas
The signal is aborted when its owning scope closes, so avoid keeping it for work that outlives that scope.
See
scopedfor binding resource lifetime to a scope
Signature
declare const abortSignal: Effect<AbortSignal, never, Scope>Since v4.0.0
interrupt
Section titled “interrupt”Returns an effect that is immediately interrupted.
Example (Creating an interrupted effect)
import { Effect } from "effect"
const program = Effect.gen(function* () { return yield* Effect.interrupt yield* Effect.succeed("This won't execute and is unreachable")})
Effect.runPromise(program).catch(console.error)// Throws: InterruptedExceptionSignature
declare const interrupt: Effect<never, never, never>Since v2.0.0
interruptible
Section titled “interruptible”Returns a new effect that allows the effect to be interruptible.
Example (Allowing interruption)
import { Effect } from "effect"
const longRunning = Effect.forever(Effect.succeed("working..."))
const program = Effect.interruptible(longRunning)
// This effect can now be interruptedconst fiber = Effect.runFork(program)// Later: fiber.interrupt()Signature
declare const interruptible: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Since v2.0.0
interruptibleMask
Section titled “interruptibleMask”Runs an effect in an interruptible region while providing restore for
locally restoring the previous interruptibility.
Example (Controlling interruptibility locally)
import { Console, Effect } from "effect"
const program = Effect.interruptibleMask((restore) => Effect.gen(function* () { yield* Console.log("Interruptible phase...") yield* Effect.sleep("1 second")
// Make this part uninterruptible yield* restore( Effect.gen(function* () { yield* Console.log("Uninterruptible phase...") yield* Effect.sleep("2 seconds") }) )
yield* Console.log("Back to interruptible") }))Signature
declare const interruptibleMask: <A, E, R>( f: (restore: <AX, EX, RX>(effect: Effect<AX, EX, RX>) => Effect<AX, EX, RX>) => Effect<A, E, R>) => Effect<A, E, R>Since v2.0.0
onInterrupt
Section titled “onInterrupt”Runs the specified finalizer effect if this effect is interrupted.
Example (Running cleanup on interruption)
import { Console, Effect, Fiber } from "effect"
const task = Effect.forever(Effect.succeed("working..."))
const program = Effect.onInterrupt(task, () => Console.log("Task was interrupted, cleaning up..."))
const fiber = Effect.runFork(program)// Later interrupt the taskEffect.runFork(Fiber.interrupt(fiber))// Output: Task was interrupted, cleaning up...Signature
declare const onInterrupt: { <XE, XR>( finalizer: (interruptors: ReadonlySet<number>) => Effect<void, XE, XR> ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | XE, R | XR> <A, E, R, XE, XR>( self: Effect<A, E, R>, finalizer: (interruptors: ReadonlySet<number>) => Effect<void, XE, XR> ): Effect<A, E | XE, R | XR>}Since v2.0.0
uninterruptible
Section titled “uninterruptible”Returns a new effect that disables interruption for the given effect.
Example (Preventing interruption)
import { Console, Effect, Fiber } from "effect"
const criticalTask = Effect.gen(function* () { yield* Console.log("Starting critical section...") yield* Effect.sleep("2 seconds") yield* Console.log("Critical section completed")})
const program = Effect.uninterruptible(criticalTask)
const fiber = Effect.runFork(program)// Even if interrupted, the critical task will completeEffect.runPromise(Fiber.interrupt(fiber))Signature
declare const uninterruptible: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Since v2.0.0
uninterruptibleMask
Section titled “uninterruptibleMask”Disables interruption and provides a restore function to restore the interruptible state within the effect.
Example (Restoring interruption in protected regions)
import { Console, Effect } from "effect"
const program = Effect.uninterruptibleMask((restore) => Effect.gen(function* () { yield* Console.log("Uninterruptible phase...") yield* Effect.sleep("1 second")
// Restore interruptibility for this part yield* restore( Effect.gen(function* () { yield* Console.log("Interruptible phase...") yield* Effect.sleep("2 seconds") }) )
yield* Console.log("Back to uninterruptible") }))Signature
declare const uninterruptibleMask: <A, E, R>( f: (restore: <AX, EX, RX>(effect: Effect<AX, EX, RX>) => Effect<AX, EX, RX>) => Effect<A, E, R>) => Effect<A, E, R>Since v2.0.0
logging
Section titled “logging”annotateLogs
Section titled “annotateLogs”Adds an annotation to each log line in this effect.
Example (Adding log annotations)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.log("Starting operation") yield* Effect.log("Processing data") yield* Effect.log("Operation completed")})
// Add annotations to all log messagesconst annotatedProgram = Effect.annotateLogs(program, { userId: "user123", operation: "data-processing"})
// Also supports single key-value annotationsconst singleAnnotated = Effect.annotateLogs(program, "requestId", "req-456")
Effect.runPromise(annotatedProgram)// All log messages will include the userId and operation annotationsSignature
declare const annotateLogs: { (key: string, value: unknown): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R> (values: Record<string, unknown>): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>} & { <A, E, R>(effect: Effect<A, E, R>, key: string, value: unknown): Effect<A, E, R> <A, E, R>(effect: Effect<A, E, R>, values: Record<string, unknown>): Effect<A, E, R>}Since v2.0.0
annotateLogsScoped
Section titled “annotateLogsScoped”Adds log annotations to the current scope.
When to use
Use to attach log annotations that last until the current scope closes.
Details
This differs from annotateLogs, which only annotates a specific effect.
annotateLogsScoped updates annotations for the entire current Scope and
restores the previous annotations when the scope closes.
Example (Adding scoped log annotations)
import { Effect } from "effect"
const program = Effect.scoped( Effect.gen(function* () { yield* Effect.log("before") yield* Effect.annotateLogsScoped({ requestId: "req-123" }) yield* Effect.log("inside scope") }))
Effect.runPromise(program)See
annotateLogsfor annotating one effect
Signature
declare const annotateLogsScoped: { (key: string, value: unknown): Effect<void, never, Scope> (values: Record<string, unknown>): Effect<void, never, Scope>}Since v3.1.0
Logs one or more messages using the default log level.
Example (Logging at the default level)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.log("Starting computation") const result = 2 + 2 yield* Effect.log("Result:", result) yield* Effect.log("Multiple", "values", "can", "be", "logged") return result})
Effect.runPromise(program).then(console.log)// Output:// timestamp=2023-... level=INFO message="Starting computation"// timestamp=2023-... level=INFO message="Result: 4"// timestamp=2023-... level=INFO message="Multiple values can be logged"// 4Signature
declare const log: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logDebug
Section titled “logDebug”Logs one or more messages at the DEBUG level.
Example (Logging debug messages)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.logDebug("Debug mode enabled")
const userInput = { name: "Alice", age: 30 } yield* Effect.logDebug("Processing user input:", userInput)
// Useful for detailed diagnostic information yield* Effect.logDebug("Variable state:", "x=10", "y=20", "z=30")})
Effect.runPromise(program)// Output:// timestamp=2023-... level=DEBUG message="Debug mode enabled"// timestamp=2023-... level=DEBUG message="Processing user input: [object Object]"// timestamp=2023-... level=DEBUG message="Variable state: x=10 y=20 z=30"Signature
declare const logDebug: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logError
Section titled “logError”Logs one or more messages at the ERROR level.
Example (Logging errors)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.logError("Database connection failed") yield* Effect.logError("Error code:", 500, "Message:", "Internal server error")
// Can be used with error objects const error = new Error("Something went wrong") yield* Effect.logError("Caught error:", error.message)})
Effect.runPromise(program)// Output:// timestamp=2023-... level=ERROR message="Database connection failed"// timestamp=2023-... level=ERROR message="Error code: 500 Message: Internal server error"// timestamp=2023-... level=ERROR message="Caught error: Something went wrong"Signature
declare const logError: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logFatal
Section titled “logFatal”Logs one or more messages at the FATAL level.
Example (Logging fatal messages)
import { Effect } from "effect"
const program = Effect.gen(function* () { try { // Simulate a critical system failure throw new Error("System memory exhausted") } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error) yield* Effect.logFatal("Critical system failure:", errorMessage) yield* Effect.logFatal("System shutting down") }})
Effect.runPromise(program)// Output:// timestamp=2023-... level=FATAL message="Critical system failure: System memory exhausted"// timestamp=2023-... level=FATAL message="System shutting down"Signature
declare const logFatal: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logInfo
Section titled “logInfo”Logs one or more messages at the INFO level.
Example (Logging information)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.logInfo("Application starting up") yield* Effect.logInfo("Config loaded:", "production", "Port:", 3000)
// Useful for general information const version = "1.2.3" yield* Effect.logInfo("Application version:", version)})
Effect.runPromise(program)// Output:// timestamp=2023-... level=INFO message="Application starting up"// timestamp=2023-... level=INFO message="Config loaded: production Port: 3000"// timestamp=2023-... level=INFO message="Application version: 1.2.3"Signature
declare const logInfo: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logTrace
Section titled “logTrace”Logs one or more messages at the TRACE level.
Example (Logging trace messages)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.logTrace("Entering function processData")
// Trace detailed execution flow for (let i = 0; i < 3; i++) { yield* Effect.logTrace("Loop iteration:", i, "Processing item") }
yield* Effect.logTrace("Exiting function processData")})
Effect.runPromise(program)// Output:// timestamp=2023-... level=TRACE message="Entering function processData"// timestamp=2023-... level=TRACE message="Loop iteration: 0 Processing item"// timestamp=2023-... level=TRACE message="Loop iteration: 1 Processing item"// timestamp=2023-... level=TRACE message="Loop iteration: 2 Processing item"// timestamp=2023-... level=TRACE message="Exiting function processData"Signature
declare const logTrace: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logWarning
Section titled “logWarning”Logs one or more messages at the WARNING level.
Example (Logging warnings)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.logWarning("API rate limit approaching") yield* Effect.logWarning("Retries remaining:", 2, "Operation:", "fetchData")
// Useful for non-critical issues const deprecated = true if (deprecated) { yield* Effect.logWarning("Using deprecated API endpoint") }})
Effect.runPromise(program)// Output:// timestamp=2023-... level=WARN message="API rate limit approaching"// timestamp=2023-... level=WARN message="Retries remaining: 2 Operation: fetchData"// timestamp=2023-... level=WARN message="Using deprecated API endpoint"Signature
declare const logWarning: (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
logWithLevel
Section titled “logWithLevel”Creates a logger function that logs at the specified level.
Details
If no level is provided, the logger uses the fiber’s current log level and
extracts any Cause values from the message list.
Example (Logging at a dynamic level)
import { Effect } from "effect"
const logWarn = Effect.logWithLevel("Warn")
const program = Effect.gen(function* () { yield* logWarn("Cache miss", { key: "user:1" })})Signature
declare const logWithLevel: (level?: Severity) => (...message: ReadonlyArray<any>) => Effect<void>Since v2.0.0
withLogSpan
Section titled “withLogSpan”Adds a span to each log line in this effect.
Example (Adding a log span)
import { Effect } from "effect"
const databaseOperation = Effect.gen(function* () { yield* Effect.log("Connecting to database") yield* Effect.log("Executing query") yield* Effect.log("Processing results") return "data"})
const httpRequest = Effect.gen(function* () { yield* Effect.log("Making HTTP request") const data = yield* Effect.withLogSpan(databaseOperation, "db-operation") yield* Effect.log("Sending response") return data})
const program = Effect.withLogSpan(httpRequest, "http-handler")
Effect.runPromise(program)// All log messages will include span information showing the nested operation contextSignature
declare const withLogSpan: ((label: string) => <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>) & (<A, E, R>(effect: Effect<A, E, R>, label: string) => Effect<A, E, R>)Since v2.0.0
withLogger
Section titled “withLogger”Adds a logger to the set of loggers which will output logs for this effect.
Example (Adding a logger to an effect)
import { Effect, Logger } from "effect"
// Create a custom logger that logs to the consoleconst customLogger = Logger.make(({ message }) => Effect.sync(() => console.log(`[CUSTOM]: ${message}`)))
const program = Effect.gen(function* () { yield* Effect.log("This will go to both default and custom logger") return "completed"})
// Add the custom logger to the effectconst programWithLogger = Effect.withLogger(program, customLogger)
Effect.runPromise(programWithLogger)// Output includes both default and custom log outputsSignature
declare const withLogger: (<Output>( logger: Logger<unknown, Output>) => <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>) & (<A, E, R, Output>(effect: Effect<A, E, R>, logger: Logger<unknown, Output>) => Effect<A, E, R>)Since v4.0.0
mapping
Section titled “mapping”Replaces the value inside an effect with a constant value.
When to use
Use to replace a successful value with a constant while preserving failures and requirements.
Details
as allows you to ignore the original value inside an effect and
replace it with a new constant value.
Example (Replacing a success value)
import { Effect, pipe } from "effect"
// Replaces the value 5 with the constant "new value"const program = pipe(Effect.succeed(5), Effect.as("new value"))
Effect.runPromise(program).then(console.log)// Output: "new value"See
mapfor deriving the replacement value from the success valueasVoidfor replacing the success value withvoid
Signature
declare const as: { <B>(value: B): <A, E, R>(self: Effect<A, E, R>) => Effect<B, E, R> <A, E, R, B>(self: Effect<A, E, R>, value: B): Effect<B, E, R>}Since v2.0.0
asSome
Section titled “asSome”Maps the success value of an Effect to Some, preserving failures.
Example (Wrapping success in Option.some)
import { Effect } from "effect"
const program = Effect.asSome(Effect.succeed(42))
Effect.runPromise(program).then(console.log)// { _id: 'Option', _tag: 'Some', value: 42 }Signature
declare const asSome: <A, E, R>(self: Effect<A, E, R>) => Effect<Option<A>, E, R>Since v2.0.0
asVoid
Section titled “asVoid”Maps the success value of an Effect to void, preserving failures.
Example (Discarding success values)
import { Effect } from "effect"
const program = Effect.asVoid(Effect.succeed(42))
Effect.runPromise(program).then(console.log)// undefined (void)Signature
declare const asVoid: <A, E, R>(self: Effect<A, E, R>) => Effect<void, E, R>Since v2.0.0
Swaps an effect’s success and failure channels.
When to use
Use to swap an Effect’s success and failure channels.
Details
For an Effect<A, E, R>, the returned effect has type Effect<E, A, R>.
Example (Swapping success and failure channels)
import { Effect } from "effect"
// ┌─── Effect<number, string, never>// ▼const program = Effect.fail("Oh uh!").pipe(Effect.as(2))
// ┌─── Effect<string, number, never>// ▼const flipped = Effect.flip(program)Signature
declare const flip: <A, E, R>(self: Effect<A, E, R>) => Effect<E, A, R>Since v2.0.0
Transforms the value inside an effect by applying a function to it.
When to use
Use to transform an effect’s success value with a function that returns a plain value, producing a new effect without changing the original effect’s typed error or context requirements.
Details
map takes a function and applies it to the value contained within an
effect, creating a new effect with the transformed value.
It’s important to note that effects are immutable, meaning that the original effect is not modified. Instead, a new effect is returned with the updated value.
Example (Choosing map syntax variants)
import { Effect, pipe } from "effect"
const myEffect = Effect.succeed(1)const transformation = (n: number) => n + 1
const mappedWithPipe = pipe(myEffect, Effect.map(transformation))const mappedWithDataFirst = Effect.map(myEffect, transformation)const mappedWithMethod = myEffect.pipe(Effect.map(transformation))Example (Adding a service charge)
import { Effect, pipe } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe(fetchTransactionAmount, Effect.map(addServiceCharge))
Effect.runPromise(finalAmount).then(console.log)// Output: 101See
mapErrorfor a version that operates on the error channel.mapBothfor a version that operates on both channels.flatMaporandThenfor a version that can return a new effect.
Signature
declare const map: { <A, B>(f: (a: A) => B): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R> <A, E, R, B>(self: Effect<A, E, R>, f: (a: A) => B): Effect<B, E, R>}Since v2.0.0
mapBoth
Section titled “mapBoth”Applies transformations to both the success and error channels of an effect.
When to use
Use to transform both success and failure channels of an Effect without
changing whether it succeeds or fails.
Details
This function takes two map functions as arguments: one for the error channel and one for the success channel. You can use it when you want to modify both the error and the success values without altering the overall success or failure status of the effect.
Example (Transforming success and failure channels)
import { Data, Effect } from "effect"
class TaskError extends Data.TaggedError("TaskError")<{ readonly message: string }> {}
// ┌─── Effect<number, string, never>// ▼const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
// ┌─── Effect<boolean, TaskError, never>// ▼const modified = Effect.mapBoth(simulatedTask, { onFailure: (message) => new TaskError({ message }), onSuccess: (n) => n > 0})See
mapfor a version that operates on the success channel.mapErrorfor a version that operates on the error channel.
Signature
declare const mapBoth: { <E, E2, A, A2>(options: { readonly onFailure: (e: E) => E2 readonly onSuccess: (a: A) => A2 }): <R>(self: Effect<A, E, R>) => Effect<A2, E2, R> <A, E, R, E2, A2>( self: Effect<A, E, R>, options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 } ): Effect<A2, E2, R>}Since v2.0.0
models
Section titled “models”Effect (interface)
Section titled “Effect (interface)”The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Signature
export interface Effect<out A, out E = never, out R = never> extends Pipeable, Inspectable { readonly [TypeId]: Variance<A, E, R> [Symbol.iterator](): EffectIterator<Effect<A, E, R>> [Unify.typeSymbol]?: unknown [Unify.unifySymbol]?: EffectUnify<this> [Unify.ignoreSymbol]?: {}}Since v2.0.0
EffectIterator (interface)
Section titled “EffectIterator (interface)”Iterator interface for Effect generators, enabling Effect values to work with generator functions.
When to use
Use when defining or typing [Symbol.iterator]() for values typed as
Effects so yield* can pass their success type back into Effect.gen.
See
genfor writing generator-basedEffectprograms that consume this iterator protocol
Signature
export interface EffectIterator<T extends Effect<any, any, any>> { next(...args: ReadonlyArray<any>): IteratorResult<T, Success<T>>}Since v4.0.0
EffectUnify (interface)
Section titled “EffectUnify (interface)”Type-level unification support for Effect values.
Signature
export interface EffectUnify<A extends { [Unify.typeSymbol]?: any }> { Effect?: () => A[Unify.typeSymbol] extends Effect<infer A0, infer E0, infer R0> | infer _ ? Effect<A0, E0, R0> : never}Since v2.0.0
Error (type alias)
Section titled “Error (type alias)”Extracts the error type from an Effect.
When to use
Use to derive the error type from an existing Effect type when declaring
helper types, wrappers, or APIs that preserve the effect’s failure channel.
Details
Non-Effect inputs resolve to never.
See
Successfor extracting the success value type insteadServicesfor extracting the required services type instead
Signature
type Error<T> = T extends Effect<infer _A, infer _E, infer _R> ? _E : neverSince v2.0.0
Services (type alias)
Section titled “Services (type alias)”Extracts the required services type from an Effect.
When to use
Use to derive the context requirements of a generic or inferred Effect
without restating its R type parameter.
See
Successfor extracting the success value type insteadErrorfor extracting the failure type instead
Signature
type Services<T> = T extends Effect<infer _A, infer _E, infer _R> ? _R : neverSince v4.0.0
Success (type alias)
Section titled “Success (type alias)”Extracts the success type from an Effect.
When to use
Use to derive the value produced by an existing effect when declaring reusable type aliases, service interfaces, or function signatures.
See
Errorfor extracting the failure type from the sameEffectServicesfor extracting the required services from the sameEffect
Signature
type Success<T> = T extends Effect<infer _A, infer _E, infer _R> ? _A : neverSince v2.0.0
Variance (interface)
Section titled “Variance (interface)”Variance interface for Effect, encoding the type parameters’ variance.
Signature
export interface Variance<A, E, R> { _A: Covariant<A> _E: Covariant<E> _R: Covariant<R>}Since v2.0.0
outcome encapsulation
Section titled “outcome encapsulation”Transforms an effect to encapsulate both failure and success using the Exit
data type.
When to use
Use when you need to inspect the full outcome, including typed failures, defects, and interruptions.
Details
exit wraps an effect’s success or failure inside an Exit type, allowing
you to handle both cases explicitly.
The resulting effect cannot fail because the failure is encapsulated within
the Exit.Failure type. The error type is set to never, indicating that
the effect is structured to never fail directly.
Example (Capturing completion as Exit)
import { Effect } from "effect"
const success = Effect.succeed(42)const failure = Effect.fail("Something went wrong")
const program1 = Effect.exit(success)const program2 = Effect.exit(failure)
Effect.runPromise(program1).then(console.log)// { _id: 'Exit', _tag: 'Success', value: 42 }
Effect.runPromise(program2).then(console.log)// { _id: 'Exit', _tag: 'Failure', cause: { _id: 'Cause', _tag: 'Fail', failure: 'Something went wrong' } }See
optionfor a version that usesOptioninstead.resultfor a version that usesResultinstead.
Signature
declare const exit: <A, E, R>(self: Effect<A, E, R>) => Effect<Exit.Exit<A, E>, never, R>Since v2.0.0
option
Section titled “option”Converts success to Option.some and failure to Option.none.
When to use
Use when you only care whether an effect succeeds and want recoverable
failures represented as Option.none.
Details
Success values become Option.some, recoverable failures become
Option.none, and defects still fail the effect.
Gotchas
option only captures typed, recoverable failures as Option.none.
Defects and interruptions are not captured inside the Option and still
fail the effect.
option also discards typed failure values. Use result if the failure
value matters.
Example (Capturing success or failure as Option)
import { Console, Effect, Option } from "effect"
const program = Effect.gen(function* () { const someValue = yield* Effect.option(Effect.succeed(1)) const noneValue = yield* Effect.option(Effect.fail("missing"))
yield* Console.log(Option.isSome(someValue)) yield* Console.log(Option.isNone(noneValue))})
Effect.runPromise(program)// true// trueSee
resultfor a version that usesResultinstead.exitfor a version that encapsulates both recoverable errors and defects in anExit.
Signature
declare const option: <A, E, R>(self: Effect<A, E, R>) => Effect<Option<A>, never, R>Since v2.0.0
result
Section titled “result”Converts both success and failure of an Effect into a Result type.
When to use
Use when you want an Effect’s typed failures to be handled as Result
data while preserving the original error value.
Details
This function converts an effect that may fail into an effect that always
succeeds, wrapping the outcome in a Result type. The result will be
Result.Failure if the effect fails, containing the recoverable error, or
Result.Success if it succeeds, containing the result.
Using this function, you can handle recoverable errors explicitly without causing the effect to fail. This is particularly useful in scenarios where you want to chain effects and manage both success and failure in the same logical flow.
The resulting effect cannot fail directly because all recoverable failures
are represented inside the Result type.
Gotchas
result only captures typed, recoverable failures. Defects and
interruptions are not captured inside the Result and still fail the
effect.
Example (Capturing success or failure as Result)
import { Effect } from "effect"
const success = Effect.succeed(42)const failure = Effect.fail("Something went wrong")
const program1 = Effect.result(success)const program2 = Effect.result(failure)
Effect.runPromise(program1).then(console.log)// { _id: 'Result', _tag: 'Success', value: 42 }
Effect.runPromise(program2).then(console.log)// { _id: 'Result', _tag: 'Failure', error: 'Something went wrong' }See
optionfor a version that usesOptioninstead.exitfor a version that encapsulates both recoverable errors and defects in anExit.
Signature
declare const result: <A, E, R>(self: Effect<A, E, R>) => Effect<Result.Result<A, E>, never, R>Since v4.0.0
pattern matching
Section titled “pattern matching”Handles both success and failure cases of an effect without performing side effects.
When to use
Use when you need to fold an Effect into a value by handling success and
failure differently without triggering side effects.
Details
match lets you define custom handlers for both success and failure
scenarios. You provide separate functions to handle each case, allowing you
to process the result if the effect succeeds, or handle the error if the
effect fails.
Example (Matching success and failure values)
import { Data, Effect } from "effect"
class ExampleError extends Data.TaggedError("ExampleError")<{ readonly message: string }> {}
const success: Effect.Effect<number, ExampleError> = Effect.succeed(42)
const program1 = Effect.match(success, { onFailure: (error) => `failure: ${error.message}`, onSuccess: (value) => `success: ${value}`})
// Run and log the result of the successful effectEffect.runPromise(program1).then(console.log)// Output: "success: 42"
const failure: Effect.Effect<number, ExampleError> = Effect.fail(new ExampleError({ message: "Uh oh!" }))
const program2 = Effect.match(failure, { onFailure: (error) => `failure: ${error.message}`, onSuccess: (value) => `success: ${value}`})
// Run and log the result of the failed effectEffect.runPromise(program2).then(console.log)// Output: "failure: Uh oh!"See
matchEffectif you need to perform side effects in the handlers.
Signature
declare const match: { <E, A2, A, A3>(options: { readonly onFailure: (error: E) => A2 readonly onSuccess: (value: A) => A3 }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, never, R> <A, E, R, A2, A3>( self: Effect<A, E, R>, options: { readonly onFailure: (error: E) => A2; readonly onSuccess: (value: A) => A3 } ): Effect<A2 | A3, never, R>}Since v2.0.0
matchCause
Section titled “matchCause”Handles failures by matching the cause of failure.
When to use
Use when you need to fold an Effect while the failure handler inspects the
full Cause.
Details
The matchCause function allows you to handle failures with access to the
full cause of the failure within a fiber.
Example (Matching on success or failure causes)
import { Cause, Effect } from "effect"
const task = Effect.fail("Something went wrong")
const program = Effect.matchCause(task, { onFailure: (cause) => `Failed: ${Cause.squash(cause)}`, onSuccess: (value) => `Success: ${value}`})
Effect.runPromise(program).then(console.log)// Output: "Failed: Error: Something went wrong"See
matchCauseEffectif you need to perform side effects in the handlers.matchif you don’t need to handle the cause of the failure.
Signature
declare const matchCause: { <E, A2, A, A3>(options: { readonly onFailure: (cause: Cause.Cause<E>) => A2 readonly onSuccess: (a: A) => A3 }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, never, R> <A, E, R, A2, A3>( self: Effect<A, E, R>, options: { readonly onFailure: (cause: Cause.Cause<E>) => A2; readonly onSuccess: (a: A) => A3 } ): Effect<A2 | A3, never, R>}Since v2.0.0
matchCauseEager
Section titled “matchCauseEager”Handles failures by matching the cause of failure with eager evaluation.
When to use
Use when you expect an Effect to already be resolved and want to match the
Cause without regular effect pipeline overhead.
Details
matchCauseEager works like matchCause but provides better performance for resolved
effects by immediately applying the matching function instead of deferring it
through the effect pipeline.
Example (Eagerly matching already completed effects)
import { Effect } from "effect"
const handleResult = Effect.matchCauseEager(Effect.succeed(42), { onSuccess: (value) => `Success: ${value}`, onFailure: (cause) => `Failed: ${cause}`})Signature
declare const matchCauseEager: { <E, A2, A, A3>(options: { readonly onFailure: (cause: Cause.Cause<E>) => A2 readonly onSuccess: (value: A) => A3 }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, never, R> <A, E, R, A2, A3>( self: Effect<A, E, R>, options: { readonly onFailure: (cause: Cause.Cause<E>) => A2; readonly onSuccess: (value: A) => A3 } ): Effect<A2 | A3, never, R>}Since v4.0.0
matchCauseEffect
Section titled “matchCauseEffect”Handles failures with access to the cause and allows performing side effects.
When to use
Use when you need to fold an Effect with effectful success handlers and
Cause-aware failure handlers.
Details
The matchCauseEffect function works similarly to matchCause, but it
also allows you to perform additional side effects based on the failure
cause. This function provides access to the complete cause of the failure,
making it possible to differentiate between various failure types, and allows
you to respond accordingly while performing side effects (like logging or
other operations).
Example (Effectfully matching on causes)
import { Cause, Console, Data, Effect, Result } from "effect"
class TaskError extends Data.TaggedError("TaskError")<{ readonly message: string }> {}
const task = Effect.fail(new TaskError({ message: "Task failed" }))
const program = Effect.matchCauseEffect(task, { onFailure: (cause) => Effect.gen(function* () { if (Cause.hasFails(cause)) { const error = Cause.findError(cause) if (Result.isSuccess(error)) { yield* Console.log(`Handling error: ${error.success.message}`) } return "recovered from error" } else { yield* Console.log("Handling interruption or defect") return "recovered from interruption/defect" } }), onSuccess: (value) => Effect.gen(function* () { yield* Console.log(`Success: ${value}`) return `processed ${value}` })})
Effect.runPromise(program).then(console.log)// Output:// Handling error: Task failed// recovered from errorSee
matchCauseif you don’t need side effects and only want to handle the result or failure.matchEffectif you don’t need to handle the cause of the failure.
Signature
declare const matchCauseEffect: { <E, A2, E2, R2, A, A3, E3, R3>(options: { readonly onFailure: (cause: Cause.Cause<E>) => Effect<A2, E2, R2> readonly onSuccess: (a: A) => Effect<A3, E3, R3> }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, E2 | E3, R2 | R3 | R> <A, E, R, A2, E2, R2, A3, E3, R3>( self: Effect<A, E, R>, options: { readonly onFailure: (cause: Cause.Cause<E>) => Effect<A2, E2, R2> readonly onSuccess: (a: A) => Effect<A3, E3, R3> } ): Effect<A2 | A3, E2 | E3, R2 | R3 | R>}Since v2.0.0
matchCauseEffectEager
Section titled “matchCauseEffectEager”Handles success or failure eagerly with effectful handlers when the effect is already resolved.
When to use
Use when you need effectful success and cause-aware failure handlers for
Effect inputs that may already be resolved.
Details
If the effect is an Exit, the matching handler runs immediately; otherwise it behaves like
matchCauseEffect.
See
matchCauseEffectfor the non-eager effectful variantmatchCauseEagerfor eager cause matching with pure handlersmatchEffectfor effectful matching on typed failures instead of full causes
Signature
declare const matchCauseEffectEager: { <E, A2, E2, R2, A, A3, E3, R3>(options: { readonly onFailure: (cause: Cause.Cause<E>) => Effect<A2, E2, R2> readonly onSuccess: (a: A) => Effect<A3, E3, R3> }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, E2 | E3, R2 | R3 | R> <A, E, R, A2, E2, R2, A3, E3, R3>( self: Effect<A, E, R>, options: { readonly onFailure: (cause: Cause.Cause<E>) => Effect<A2, E2, R2> readonly onSuccess: (a: A) => Effect<A3, E3, R3> } ): Effect<A2 | A3, E2 | E3, R2 | R3 | R>}Since v4.0.0
matchEager
Section titled “matchEager”Handles both success and failure cases of an effect without performing side effects, with eager evaluation for resolved effects.
When to use
Use when you need to handle both success and failure cases of an
already-resolved Effect with optimized handling.
Details
matchEager works like match but provides better performance for resolved
effects (Success or Failure). When the effect is already resolved, it applies
the handlers immediately without fiber scheduling. For unresolved effects,
it falls back to the regular match behavior.
Example (Pattern matching eagerly when possible)
import { Effect } from "effect"
const program = Effect.gen(function* () { const result = yield* Effect.matchEager(Effect.succeed(42), { onFailure: (error) => `Failed: ${error}`, onSuccess: (value) => `Success: ${value}` }) console.log(result) // "Success: 42"})See
matchfor the non-eager version.matchEffectif you need to perform side effects in the handlers.
Signature
declare const matchEager: { <E, A2, A, A3>(options: { readonly onFailure: (error: E) => A2 readonly onSuccess: (value: A) => A3 }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, never, R> <A, E, R, A2, A3>( self: Effect<A, E, R>, options: { readonly onFailure: (error: E) => A2; readonly onSuccess: (value: A) => A3 } ): Effect<A2 | A3, never, R>}Since v4.0.0
matchEffect
Section titled “matchEffect”Handles both success and failure by running effectful handlers.
When to use
Use when you need to handle an Effect’s failure or success with handlers
that return effects.
Details
Use matchEffect when either branch needs to return an Effect, such as
performing logging, recovery, notification, or other effectful work. The
returned effect succeeds or fails according to the handler that is run.
Example (Matching success and failure with effectful handlers)
import { Data, Effect } from "effect"
class ExampleError extends Data.TaggedError("ExampleError")<{ readonly message: string }> {}
const success: Effect.Effect<number, ExampleError> = Effect.succeed(42)const failure: Effect.Effect<number, ExampleError> = Effect.fail(new ExampleError({ message: "Uh oh!" }))
const program1 = Effect.matchEffect(success, { onFailure: (error) => Effect.succeed(`failure: ${error.message}`).pipe(Effect.tap(Effect.log)), onSuccess: (value) => Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))})
console.log(Effect.runSync(program1))// Output:// timestamp=... level=INFO fiber=#0 message="success: 42"// success: 42
const program2 = Effect.matchEffect(failure, { onFailure: (error) => Effect.succeed(`failure: ${error.message}`).pipe(Effect.tap(Effect.log)), onSuccess: (value) => Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))})
console.log(Effect.runSync(program2))// Output:// timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"// failure: Uh oh!See
matchif you don’t need side effects and only want to handle the result or failure.
Signature
declare const matchEffect: { <E, A2, E2, R2, A, A3, E3, R3>(options: { readonly onFailure: (e: E) => Effect<A2, E2, R2> readonly onSuccess: (a: A) => Effect<A3, E3, R3> }): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, E2 | E3, R2 | R3 | R> <A, E, R, A2, E2, R2, A3, E3, R3>( self: Effect<A, E, R>, options: { readonly onFailure: (e: E) => Effect<A2, E2, R2>; readonly onSuccess: (a: A) => Effect<A3, E3, R3> } ): Effect<A2 | A3, E2 | E3, R2 | R3 | R>}Since v2.0.0
racing
Section titled “racing”Races two effects and returns the first successful result.
Details
If one effect succeeds, the other is interrupted and onWinner can observe the
winning fiber. If both fail, the race fails.
Example (Racing two effects)
import { Console, Duration, Effect } from "effect"
const fastFail = Effect.delay(Effect.fail("fast-fail"), Duration.millis(10))const slowSuccess = Effect.delay(Effect.succeed("slow-success"), Duration.millis(50))
const program = Effect.gen(function* () { const result = yield* Effect.race(fastFail, slowSuccess) yield* Console.log(`winner: ${result}`)})
Effect.runPromise(program)// Output: winner: slow-successSignature
declare const race: { <A2, E2, R2>( that: Effect<A2, E2, R2>, options?: { readonly onWinner?: (options: { readonly fiber: Fiber<any, any> readonly index: number readonly parentFiber: Fiber<any, any> }) => void } ): <A, E, R>(self: Effect<A, E, R>) => Effect<A | A2, E | E2, R | R2> <A, E, R, A2, E2, R2>( self: Effect<A, E, R>, that: Effect<A2, E2, R2>, options?: { readonly onWinner?: (options: { readonly fiber: Fiber<any, any> readonly index: number readonly parentFiber: Fiber<any, any> }) => void } ): Effect<A | A2, E | E2, R | R2>}Since v2.0.0
raceAll
Section titled “raceAll”Runs multiple effects concurrently and returns the first successful result.
When to use
Use when early failures should be ignored until a success occurs or all effects fail.
Details
Early failures do not finish the race; raceAll keeps waiting until one
effect succeeds or every effect has failed. When one effect succeeds, the
remaining effects are interrupted. If every effect fails, the returned effect
fails with a cause containing the collected failure reasons.
Example (Racing many effects)
import { Duration, Effect } from "effect"
// Multiple effects with different delaysconst effect1 = Effect.delay(Effect.succeed("Fast"), Duration.millis(100))const effect2 = Effect.delay(Effect.succeed("Slow"), Duration.millis(500))const effect3 = Effect.delay(Effect.succeed("Very Slow"), Duration.millis(1000))
// Race all effects - the first to succeed winsconst raced = Effect.raceAll([effect1, effect2, effect3])
// Result: "Fast" (after ~100ms)See
racefor a version that handles only two effects.
Signature
declare const raceAll: <Eff extends Effect<any, any, any>>( all: Iterable<Eff>, options?: { readonly onWinner?: (options: { readonly fiber: Fiber<any, any> readonly index: number readonly parentFiber: Fiber<any, any> }) => void }) => Effect<Success<Eff>, Error<Eff>, Services<Eff>>Since v2.0.0
raceAllFirst
Section titled “raceAllFirst”Runs multiple effects concurrently and completes with the first effect to finish, whether it succeeds or fails.
Details
After the first effect completes, all remaining effects are interrupted. Use
raceAll when early failures should be ignored until a success occurs or
all effects fail.
Example (Taking the first settled result)
import { Duration, Effect } from "effect"
// Multiple effects with different delays and potential failuresconst effect1 = Effect.delay(Effect.succeed("First"), Duration.millis(200))const effect2 = Effect.delay(Effect.fail("Second failed"), Duration.millis(100))const effect3 = Effect.delay(Effect.succeed("Third"), Duration.millis(300))
// Race all effects - the first to succeed winsconst raced = Effect.raceAllFirst([effect1, effect2, effect3])
// Result: "First" (after ~200ms, even though effect2 completes first but fails)Signature
declare const raceAllFirst: <Eff extends Effect<any, any, any>>( all: Iterable<Eff>, options?: { readonly onWinner?: (options: { readonly fiber: Fiber<any, any> readonly index: number readonly parentFiber: Fiber<any, any> }) => void }) => Effect<Success<Eff>, Error<Eff>, Services<Eff>>Since v4.0.0
raceFirst
Section titled “raceFirst”Races two effects and returns the result of the first one to complete, whether it succeeds or fails.
When to use
Use when any completion, including failure, should decide the race and interrupt the losing effect.
Details
The losing effect is interrupted, and onWinner can observe the winning fiber.
Example (Observing the winning fiber)
import { Console, Duration, Effect } from "effect"
const fastFail = Effect.delay(Effect.fail("fast-fail"), Duration.millis(10))const slowSuccess = Effect.delay(Effect.succeed("slow-success"), Duration.millis(50))
const program = Effect.gen(function* () { const message = yield* Effect.match(Effect.raceFirst(fastFail, slowSuccess), { onFailure: (error) => `failed: ${error}`, onSuccess: (value) => `succeeded: ${value}` }) yield* Console.log(message)})
Effect.runPromise(program)// Output: failed: fast-failSignature
declare const raceFirst: { <A2, E2, R2>( that: Effect<A2, E2, R2>, options?: { readonly onWinner?: (options: { readonly fiber: Fiber<any, any> readonly index: number readonly parentFiber: Fiber<any, any> }) => void } ): <A, E, R>(self: Effect<A, E, R>) => Effect<A | A2, E | E2, R | R2> <A, E, R, A2, E2, R2>( self: Effect<A, E, R>, that: Effect<A2, E2, R2>, options?: { readonly onWinner?: (options: { readonly fiber: Fiber<any, any> readonly index: number readonly parentFiber: Fiber<any, any> }) => void } ): Effect<A | A2, E | E2, R | R2>}Since v2.0.0
references
Section titled “references”withConcurrency
Section titled “withConcurrency”Sets the concurrency level for parallel operations within an effect.
Example (Setting local concurrency)
import { Console, Effect } from "effect"
const task = (id: number) => Effect.gen(function* () { yield* Console.log(`Task ${id} starting`) yield* Effect.sleep("100 millis") yield* Console.log(`Task ${id} completed`) return id })
// Run tasks with limited concurrency (max 2 at a time)const program = Effect.gen(function* () { const tasks = [1, 2, 3, 4, 5].map(task) return yield* Effect.all(tasks, { concurrency: 2 })}).pipe(Effect.withConcurrency(2))
Effect.runPromise(program).then(console.log)// Tasks will run with max 2 concurrent operations// [1, 2, 3, 4, 5]Signature
declare const withConcurrency: { (concurrency: number | "unbounded"): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>(self: Effect<A, E, R>, concurrency: number | "unbounded"): Effect<A, E, R>}Since v2.0.0
repetition
Section titled “repetition”eventually
Section titled “eventually”Retries an effect until it succeeds, discarding failures.
Details
Yields between attempts so other fibers can run.
Example (Retrying until success)
import { Console, Effect } from "effect"
let attempts = 0
const flaky = Effect.gen(function* () { attempts++ yield* Console.log(`Attempt ${attempts}`) if (attempts < 3) { return yield* Effect.fail("Not ready") } return "Ready"})
const program = Effect.eventually(flaky)
Effect.runPromise(program).then(console.log)// Output:// Attempt 1// Attempt 2// Attempt 3// ReadySignature
declare const eventually: <A, E, R>(self: Effect<A, E, R>) => Effect<A, never, R>Since v2.0.0
forever
Section titled “forever”Repeats this effect forever (until the first error).
Example (Repeating forever)
import { Console, Effect, Fiber } from "effect"
const task = Effect.gen(function* () { yield* Console.log("Task running...") yield* Effect.sleep("1 second")})
// This will run forever, printing every secondconst program = task.pipe(Effect.forever)
// This will run forever, without yielding every iterationconst programNoYield = task.pipe(Effect.forever({ disableYield: true }))
// Run for 5 seconds then interruptconst timedProgram = Effect.gen(function* () { const fiber = yield* Effect.forkChild(program) yield* Effect.sleep("5 seconds") yield* Fiber.interrupt(fiber)})Signature
declare const forever: < Arg extends Effect<any, any, any> | { readonly disableYield?: boolean | undefined } | undefined = { readonly disableYield?: boolean | undefined }>( effectOrOptions?: Arg, options?: { readonly disableYield?: boolean | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Effect<never, _E, _R> : <A, E, R>(self: Effect<A, E, R>) => Effect<never, E, R>Since v2.0.0
repeat
Section titled “repeat”Repeats an effect based on a specified schedule or until the first failure.
When to use
Use to rerun an effect after successful executions.
Details
This function executes an effect repeatedly according to the given schedule.
Each repetition occurs after the initial execution of the effect, meaning
that the schedule determines the number of additional repetitions. For
example, using Schedule.once will result in the effect being executed twice
(once initially and once as part of the repetition).
If the effect succeeds, it is repeated according to the schedule. If it fails, the repetition stops immediately, and the failure is returned.
The schedule can also specify delays between repetitions, making it useful for tasks like retrying operations with backoff, periodic execution, or performing a series of dependent actions.
You can combine schedules for more advanced repetition logic, such as adding delays, limiting recursions, or dynamically adjusting based on the outcome of each execution.
Gotchas
The source effect is always evaluated once before the schedule is stepped. The schedule controls additional repetitions, not the initial execution.
Example (Repeating successful effects with a schedule)
// Success Exampleimport { Console, Effect, Schedule } from "effect"
const action = Console.log("success")const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))const program = Effect.repeat(action, policy)
// Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))Example (Stopping repetition on failure)
// Failure Exampleimport { Effect, Schedule } from "effect"
let count = 0
// Define a callback effect that simulates an action with possible failuresconst action = Effect.callback<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), () => Effect.succeed("100 millis"))const program = Effect.repeat(action, policy)
// Effect.runPromiseExit(program).then(console.log)See
retryfor failure-based repetitionrepeatOrElsefor fallback handling when repetition fails
Signature
declare const repeat: { <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O> <Output, Input, Error, Env>( schedule: Schedule<Output, NoInfer<Input>, Error, Env> ): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env> <Output, Input, Error, Env>( builder: ( $: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R> ) => Schedule<Output, NoInfer<Input>, Error, Env> ): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env> <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O> <Input, E, R, Output, Error, Env>( self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env> ): Effect<Output, E | Error, R | Env> <Input, E, R, Output, Error, Env>( self: Effect<Input, E, R>, builder: ( $: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R> ) => Schedule<Output, NoInfer<Input>, Error, Env> ): Effect<Output, E | Error, R | Env>}Since v2.0.0
repeatOrElse
Section titled “repeatOrElse”Repeats an effect according to a schedule and runs a fallback effect if repetition fails before the schedule completes.
When to use
Use when successful repetitions should follow a schedule, but failures from the repeated effect or schedule need an effectful fallback.
Details
If the repeated effect or schedule step fails, orElse receives the failure
and the latest schedule metadata when at least one schedule step has run;
otherwise it receives None. If the schedule completes normally, the
returned effect succeeds with the schedule’s output.
Example (Recovering after repetition stops)
import { Console, Effect, Option, Schedule } from "effect"
let attempt = 0const task = Effect.gen(function* () { attempt++ if (attempt <= 2) { yield* Console.log(`Attempt ${attempt} failed`) return yield* Effect.fail(`Error ${attempt}`) } yield* Console.log(`Attempt ${attempt} succeeded`) return "success"})
const program = Effect.repeatOrElse(task, Schedule.recurs(3), (error, attempts) => Console.log(`Final failure: ${error}, after ${Option.getOrElse(attempts, () => 0)} attempts`).pipe( Effect.map(() => 0) ))Signature
declare const repeatOrElse: { <R2, A, B, E, E2, E3, R3>( schedule: Schedule<B, A, E2, R2>, orElse: (error: E | E2, option: Option<B>) => Effect<B, E3, R3> ): <R>(self: Effect<A, E, R>) => Effect<B, E3, R | R2 | R3> <A, E, R, R2, B, E2, E3, R3>( self: Effect<A, E, R>, schedule: Schedule<B, A, E2, R2>, orElse: (error: E | E2, option: Option<B>) => Effect<B, E3, R3> ): Effect<B, E3, R | R2 | R3>}Since v2.0.0
schedule
Section titled “schedule”Runs an effect repeatedly according to a schedule and returns the schedule’s final output.
When to use
Use to rerun a successful effect according to a Schedule when the schedule
does not need a custom initial input.
Details
The schedule is first stepped with undefined. After each successful
execution, the effect’s success value is fed to the schedule to decide
whether to run again. The returned effect fails if the effect or schedule
fails, and otherwise succeeds with the schedule output when the schedule
completes.
Example (Scheduling repeated execution)
import { Console, Effect, Schedule } from "effect"
const task = Effect.gen(function* () { yield* Console.log("Task executing...") return Math.random()})
// Repeat 3 times with 1 second delay between executionsconst program = Effect.schedule( task, Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("1 second")))
Effect.runPromise(program).then(console.log)// Output:// Task executing... (immediate)// Task executing... (after 1 second)// Task executing... (after 1 second)// Returns the count from Schedule.recursSee
scheduleFromfor a variant that allows the schedule’s decision to depend on the result of this effect.
Signature
declare const schedule: { <Output, Error, Env>( schedule: Schedule<Output, unknown, Error, Env> ): <A, E, R>(self: Effect<A, E, R>) => Effect<Output, E, R | Env> <A, E, R, Output, Error, Env>( self: Effect<A, E, R>, schedule: Schedule<Output, unknown, Error, Env> ): Effect<Output, E, R | Env>}Since v2.0.0
scheduleFrom
Section titled “scheduleFrom”Runs an effect repeatedly according to a schedule that is initialized with a specific schedule input.
Details
initial is passed to the schedule before the first execution, not to the
effect itself. After each successful execution, the effect’s success value is
fed back into the schedule to decide whether to continue. The returned effect
succeeds with the schedule output when the schedule completes and fails if
the effect or schedule fails.
Example (Scheduling from an initial value)
import { Console, Effect, Schedule } from "effect"
const task = (input: number) => Effect.gen(function* () { yield* Console.log(`Processing: ${input}`) return input + 1 })
// Start with 0, repeat 3 timesconst program = Effect.scheduleFrom(task(0), 0, Schedule.recurs(2))
Effect.runPromise(program).then(console.log)// Returns the schedule countSignature
declare const scheduleFrom: { <Input, Output, Error, Env>( initial: Input, schedule: Schedule<Output, Input, Error, Env> ): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E, R | Env> <Input, E, R, Output, Error, Env>( self: Effect<Input, E, R>, initial: Input, schedule: Schedule<Output, Input, Error, Env> ): Effect<Output, E, R | Env>}Since v2.0.0
requests & batching
Section titled “requests & batching”request
Section titled “request”Executes a request using the provided resolver.
When to use
Use when you need resolver-driven batching for a typed Request.
Example (Executing a request through a resolver)
import { Console, Effect, Exit, Request, RequestResolver } from "effect"
interface GetUser extends Request.Request<string> { readonly _tag: "GetUser" readonly id: number}const GetUser = Request.tagged<GetUser>("GetUser")
const resolver = RequestResolver.make<GetUser>( Effect.fnUntraced(function* (entries) { for (const entry of entries) { yield* Request.complete(entry, Exit.succeed(`user-${entry.request.id}`)) } }))
const program = Effect.gen(function* () { const name = yield* Effect.request(GetUser({ id: 1 }), resolver) yield* Console.log(name)})See
requestUnsafefor the low-level entry point when you already have aContextand need to enqueue outside anEffect
Signature
declare const request: { <A extends Request.Any, EX = never, RX = never>( resolver: RequestResolver<A> | Effect<RequestResolver<A>, EX, RX> ): (self: A) => Effect<Request.Success<A>, Request.Error<A> | EX, Request.Services<A> | RX> <A extends Request.Any, EX = never, RX = never>( self: A, resolver: RequestResolver<A> | Effect<RequestResolver<A>, EX, RX> ): Effect<Request.Success<A>, Request.Error<A> | EX, Request.Services<A> | RX>}Since v2.0.0
requestUnsafe
Section titled “requestUnsafe”Registers a request with a resolver and delivers the exit value via onExit.
When to use
Use when you already have a Context and need to enqueue a request outside
an Effect while receiving completion through onExit.
Details
It returns a canceler that removes the pending request entry.
See
requestfor theEffect-returning API used for normal request execution
Signature
declare const requestUnsafe: <A extends Request.Any>( self: A, options: { readonly resolver: RequestResolver<A> readonly onExit: (exit: Exit.Exit<Request.Success<A>, Request.Error<A>>) => void readonly context: Context.Context<never> }) => () => voidSince v4.0.0
resource management
Section titled “resource management”acquireDisposable
Section titled “acquireDisposable”Acquires a scoped resource that implements JavaScript disposal protocols.
When to use
Use when you work with JavaScript Disposable or AsyncDisposable resources
that should be closed with the surrounding scope.
Details
The resource is automatically disposed when the surrounding
Scope is closed, using Symbol.dispose for
synchronous disposables or Symbol.asyncDispose for asynchronous
disposables.
This is similar to acquireRelease, but uses the standard
JavaScript disposal protocol instead of requiring an explicit release
function. It works with JavaScript Disposable and AsyncDisposable
resources.
Example (Acquiring a disposable resource)
import sqlite from "node:sqlite"import { Effect } from "effect"
const program = Effect.scoped( Effect.gen(function* () { // acquire database connection // database will be closed when the scope is closed const db = yield* Effect.acquireDisposable(Effect.sync(() => new sqlite.DatabaseSync(":memory:")))
const row = db.prepare("SELECT 1 AS value").get() yield* Effect.log(row) // { value: 1 } }))See
acquireReleasefor resources that need an explicit finalizer
Signature
declare const acquireDisposable: <A extends AsyncDisposable | Disposable, E, R>( acquire: Effect<A, E, R>) => Effect<A, E, R | Scope>Since v4.0.0
acquireRelease
Section titled “acquireRelease”Constructs a scoped resource from an acquisition effect and a release finalizer.
When to use
Use to acquire a scoped resource with an explicit release finalizer.
Details
If acquisition succeeds, the release finalizer is added to the current scope
and is guaranteed to run when that scope closes. The finalizer receives the
Exit value used to close the scope.
By default, acquisition is protected by an uninterruptible region. Pass
{ interruptible: true } to allow the acquisition effect to be interrupted.
Example (Acquiring and releasing a resource)
import { Console, Effect, Exit } from "effect"
// Simulate a resource that needs cleanupinterface FileHandle { readonly path: string readonly content: string}
// Acquire a file handleconst acquire = Effect.gen(function* () { yield* Console.log("Opening file") return { path: "/tmp/file.txt", content: "file content" }})
// Release the file handleconst release = (handle: FileHandle, exit: Exit.Exit<unknown, unknown>) => Console.log(`Closing file ${handle.path} with exit: ${Exit.isSuccess(exit) ? "success" : "failure"}`)
// Create a scoped resourceconst resource = Effect.acquireRelease(acquire, release)
// Use the resource within a scopeconst program = Effect.scoped( Effect.gen(function* () { const handle = yield* resource yield* Console.log(`Using file: ${handle.path}`) return handle.content }))See
acquireDisposablefor resources that implement JavaScript disposal protocolsacquireUseReleasefor bracketing acquire, use, and release in one effect
Signature
declare const acquireRelease: <A, E, R, R2>( acquire: Effect<A, E, R>, release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect<unknown, never, R2>, options?: { readonly interruptible?: boolean }) => Effect<A, E, R | R2 | Scope>Since v2.0.0
acquireUseRelease
Section titled “acquireUseRelease”Runs resource acquisition, usage, and release as one bracketed effect.
When to use
Use to bracket acquire, use, and release logic in one effect.
Details
acquireUseRelease does the following:
- Ensures that the
Effectvalue that acquires the resource will not be interrupted. Note that acquisition may still fail due to internal reasons (such as an uncaught exception). - Ensures that the
releaseEffectvalue will not be interrupted, and will be executed as long as the acquisitionEffectvalue successfully acquires the resource.
During the time period between the acquisition and release of the resource,
the use Effect value will be executed.
If the release Effect value fails, then the entire Effect value will
fail, even if the use Effect value succeeds. If this fail-fast behavior
is not desired, errors produced by the release Effect value can be caught
and ignored.
Example (Acquiring resources with cleanup)
import { Console, Effect, Exit } from "effect"
interface Database { readonly connection: string readonly query: (sql: string) => Effect.Effect<string>}
const program = Effect.acquireUseRelease( // Acquire - connect to database Effect.gen(function* () { yield* Console.log("Connecting to database...") return { connection: "db://localhost:5432", query: (sql: string) => Effect.succeed(`Result for: ${sql}`) } }), // Use - perform database operations (db) => Effect.gen(function* () { yield* Console.log(`Connected to ${db.connection}`) const result = yield* db.query("SELECT * FROM users") yield* Console.log(`Query result: ${result}`) return result }), // Release - close database connection (db, exit) => Effect.gen(function* () { if (Exit.isSuccess(exit)) { yield* Console.log(`Closing connection to ${db.connection} (success)`) } else { yield* Console.log(`Closing connection to ${db.connection} (failure)`) } }))
Effect.runPromise(program)// Output:// Connecting to database...// Connected to db://localhost:5432// Query result: Result for: SELECT * FROM users// Closing connection to db://localhost:5432 (success)See
acquireReleasefor scoped resources whose use happens later
Signature
declare const acquireUseRelease: <Resource, E, R, A, E2, R2, E3, R3>( acquire: Effect<Resource, E, R>, use: (a: Resource) => Effect<A, E2, R2>, release: (a: Resource, exit: Exit.Exit<A, E2>) => Effect<void, E3, R3>) => Effect<A, E | E2 | E3, R | R2 | R3>Since v2.0.0
addFinalizer
Section titled “addFinalizer”Adds a finalizer to the current scope.
When to use
Use to register low-level cleanup in the current scope.
Details
The finalizer runs when the surrounding scope is closed and receives the
Exit value used to close the scope.
Example (Registering scope finalizers)
import { Console, Effect, Exit } from "effect"
const program = Effect.scoped( Effect.gen(function* () { // Add a finalizer that runs when the scope closes yield* Effect.addFinalizer((exit) => Console.log( Exit.isSuccess(exit) ? "Cleanup: Operation completed successfully" : "Cleanup: Operation failed, cleaning up resources" ) )
yield* Console.log("Performing main operation...")
// This could succeed or fail return "operation result" }))
Effect.runPromise(program).then(console.log)// Output:// Performing main operation...// Cleanup: Operation completed successfully// operation resultSee
acquireReleasefor resource acquisition with a release finalizerensuringfor attaching a finalizer to one effect
Signature
declare const addFinalizer: <R>( finalizer: (exit: Exit.Exit<unknown, unknown>) => Effect<void, never, R>) => Effect<void, never, R | Scope>Since v2.0.0
ensuring
Section titled “ensuring”Returns an effect that, if this effect starts execution, then the
specified finalizer is guaranteed to be executed, whether this effect
succeeds, fails, or is interrupted.
Details
For use cases that need access to the effect’s result, see onExit.
Finalizers offer very powerful guarantees, but they are low-level, and
should generally not be used for releasing resources. For higher-level
logic built on ensuring, see the acquireRelease family of methods.
Example (Always running cleanup)
import { Console, Effect } from "effect"
const task = Effect.gen(function* () { yield* Console.log("Task started") yield* Effect.sleep("1 second") yield* Console.log("Task completed") return 42})
// Ensure cleanup always runs, regardless of success or failureconst program = Effect.ensuring(task, Console.log("Cleanup: This always runs!"))
Effect.runPromise(program).then(console.log)// Output:// Task started// Task completed// Cleanup: This always runs!// 42Signature
declare const ensuring: { <X, R1>(finalizer: Effect<X, never, R1>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R1 | R> <A, E, R, X, R1>(self: Effect<A, E, R>, finalizer: Effect<X, never, R1>): Effect<A, E, R1 | R>}Since v2.0.0
onError
Section titled “onError”Runs the specified effect if this effect fails, providing the error to the effect if it exists. The provided effect will not be interrupted.
Example (Running cleanup on failure)
import { Cause, Console, Data, Effect } from "effect"
class TaskError extends Data.TaggedError("TaskError")<{ readonly message: string }> {}
const task = Effect.fail(new TaskError({ message: "Something went wrong" }))
const program = Effect.onError(task, (cause) => Console.log(`Cleanup on error: ${Cause.squash(cause)}`))
Effect.runPromise(program).catch(console.error)// Output:// Cleanup on error: TaskError: Something went wrong// TaskError: Something went wrongSignature
declare const onError: { <E, X, R2>( cleanup: (cause: Cause.Cause<E>) => Effect<X, never, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R2 | R> <A, E, R, X, R2>( self: Effect<A, E, R>, cleanup: (cause: Cause.Cause<E>) => Effect<X, never, R2> ): Effect<A, E, R2 | R>}Since v2.0.0
onErrorFilter
Section titled “onErrorFilter”Runs the finalizer only when this effect fails and the cause matches the provided Filter.
When to use
Use when cleanup or diagnostics should run only for failures whose full
Cause is accepted or transformed by a Filter, and the finalizer needs the
filter’s pass value plus the original cause.
See
onErrorfor cleanup on every failureonErrorIffor selecting failures with a boolean predicateonExitFilterfor selecting from every exit instead of only failures
Signature
declare const onErrorFilter: { <A, E, EB, X, XE, XR>( filter: Filter.Filter<Cause.Cause<E>, EB, X>, f: (failure: EB, cause: Cause.Cause<E>) => Effect<void, XE, XR> ): <R>(self: Effect<A, E, R>) => Effect<A, E | XE, R | XR> <A, E, R, EB, X, XE, XR>( self: Effect<A, E, R>, filter: Filter.Filter<Cause.Cause<E>, EB, X>, f: (failure: EB, cause: Cause.Cause<E>) => Effect<void, XE, XR> ): Effect<A, E | XE, R | XR>}Since v4.0.0
onErrorIf
Section titled “onErrorIf”Runs the finalizer only when this effect fails and the Cause matches the
provided predicate.
Example (Running cleanup for selected failures)
import { Cause, Console, Effect } from "effect"
const task = Effect.fail("boom")
const program = Effect.onErrorIf(task, Cause.hasFails, (cause) => Effect.gen(function* () { yield* Console.log(`Cause: ${Cause.pretty(cause)}`) }))Signature
declare const onErrorIf: { <E, XE, XR>( predicate: Predicate.Predicate<Cause.Cause<E>>, f: (cause: Cause.Cause<E>) => Effect<void, XE, XR> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | XE, R | XR> <A, E, R, XE, XR>( self: Effect<A, E, R>, predicate: Predicate.Predicate<Cause.Cause<E>>, f: (cause: Cause.Cause<E>) => Effect<void, XE, XR> ): Effect<A, E | XE, R | XR>}Since v4.0.0
onExit
Section titled “onExit”Ensures that a cleanup function runs whether this effect succeeds, fails, or is interrupted.
Example (Observing every exit)
import { Console, Effect, Exit } from "effect"
const task = Effect.succeed(42)
const program = Effect.onExit(task, (exit) => Console.log( Exit.isSuccess(exit) ? `Task succeeded with: ${exit.value}` : `Task failed: ${Exit.isFailure(exit) ? exit.cause : "interrupted"}` ))
Effect.runPromise(program).then(console.log)// Output:// Task succeeded with: 42// 42Signature
declare const onExit: { <A, E, XE = never, XR = never>( f: (exit: Exit.Exit<A, E>) => Effect<void, XE, XR> ): <R>(self: Effect<A, E, R>) => Effect<A, E | XE, R | XR> <A, E, R, XE = never, XR = never>( self: Effect<A, E, R>, f: (exit: Exit.Exit<A, E>) => Effect<void, XE, XR> ): Effect<A, E | XE, R | XR>}Since v2.0.0
onExitFilter
Section titled “onExitFilter”Runs the cleanup effect only when the Exit matches the provided Filter.
When to use
Use when cleanup should run only for Exit values selected by a Filter,
and the cleanup needs the extracted pass value together with the original
Exit.
Details
Result.fail skips cleanup, and Result.succeed runs cleanup with the
selected value and the original Exit.
See
onExitfor cleanup on every exitonExitIffor selecting exits with a boolean predicateonErrorFilterfor selecting only failure causes
Signature
declare const onExitFilter: { <A, E, XE, XR, B, X>( filter: Filter.Filter<Exit.Exit<NoInfer<A>, NoInfer<E>>, B, X>, f: (b: B, exit: Exit.Exit<NoInfer<A>, NoInfer<E>>) => Effect<void, XE, XR> ): <R>(self: Effect<A, E, R>) => Effect<A, E | XE, R | XR> <A, E, R, XE, XR, B, X>( self: Effect<A, E, R>, filter: Filter.Filter<Exit.Exit<NoInfer<A>, NoInfer<E>>, B, X>, f: (b: B, exit: Exit.Exit<NoInfer<A>, NoInfer<E>>) => Effect<void, XE, XR> ): Effect<A, E | XE, R | XR>}Since v4.0.0
onExitIf
Section titled “onExitIf”Runs the cleanup effect only when the Exit satisfies the provided
predicate.
Example (Observing selected exits)
import { Console, Effect, Exit } from "effect"
const program = Effect.onExitIf(Effect.succeed(42), Exit.isSuccess, (exit) => Exit.isSuccess(exit) ? Console.log(`Succeeded with: ${exit.value}`) : Effect.void)Signature
declare const onExitIf: { <A, E, XE, XR>( predicate: Predicate.Predicate<Exit.Exit<NoInfer<A>, NoInfer<E>>>, f: (exit: Exit.Exit<NoInfer<A>, NoInfer<E>>) => Effect<void, XE, XR> ): <R>(self: Effect<A, E, R>) => Effect<A, E | XE, R | XR> <A, E, R, XE, XR>( self: Effect<A, E, R>, predicate: Predicate.Predicate<Exit.Exit<NoInfer<A>, NoInfer<E>>>, f: (exit: Exit.Exit<NoInfer<A>, NoInfer<E>>) => Effect<void, XE, XR> ): Effect<A, E | XE, R | XR>}Since v4.0.0
onExitPrimitive
Section titled “onExitPrimitive”Runs an optional finalizer with the effect’s Exit value when the effect
completes.
When to use
Use when you are building a low-level Effect operator that must inspect the
source effect’s Exit, may skip finalization by returning undefined, or
must choose whether finalization is forced into an uninterruptible region.
Details
This low-level operator preserves the source effect’s result unless the
finalizer fails. Prefer onExit for normal cleanup logic.
See
onExitfor ordinary exit-aware cleanup whose finalizer always returns an effect
Signature
declare const onExitPrimitive: <A, E, R, XE = never, XR = never>( self: Effect<A, E, R>, f: (exit: Exit.Exit<A, E>) => Effect<void, XE, XR> | undefined, interruptible?: boolean) => Effect<A, E | XE, R | XR>Since v4.0.0
Returns the current scope for resource management.
Example (Accessing the current scope)
import { Console, Effect } from "effect"
const program = Effect.gen(function* () { const currentScope = yield* Effect.scope yield* Console.log("Got scope for resource management")
// Use the scope to manually manage resources if needed const resource = yield* Effect.acquireRelease(Console.log("Acquiring resource").pipe(Effect.as("resource")), () => Console.log("Releasing resource") )
return resource})
Effect.runPromise(Effect.scoped(program)).then(console.log)// Output:// Got scope for resource management// Acquiring resource// resource// Releasing resourceSignature
declare const scope: Effect<Scope, never, Scope>Since v2.0.0
scoped
Section titled “scoped”Runs an effect with a scope that closes when the effect completes.
When to use
Use to acquire scoped resources for the duration of a single workflow.
Details
Finalizers for resources acquired inside the workflow run as soon as the workflow completes, whether by success, failure, or interruption.
Example (Running a scoped acquisition)
import { Console, Effect } from "effect"
const resource = Effect.acquireRelease(Console.log("Acquiring resource").pipe(Effect.as("resource")), () => Console.log("Releasing resource"))
const program = Effect.scoped( Effect.gen(function* () { const res = yield* resource yield* Console.log(`Using ${res}`) return res }))
Effect.runFork(program)// Output: "Acquiring resource"// Output: "Using resource"// Output: "Releasing resource"Signature
declare const scoped: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, Scope>>Since v2.0.0
scopedWith
Section titled “scopedWith”Creates a scoped effect by providing access to the scope.
When to use
Use when resource acquisition needs direct access to the scope being created, for example to register finalizers manually.
Example (Working with an explicit scope)
import { Console, Effect, Scope } from "effect"
const program = Effect.scopedWith((scope) => Effect.gen(function* () { yield* Console.log("Inside scoped context")
// Manually add a finalizer to the scope yield* Scope.addFinalizer(scope, Console.log("Manual finalizer"))
// Create a scoped resource const resource = yield* Effect.scoped( Effect.acquireRelease(Console.log("Acquiring resource").pipe(Effect.as("resource")), () => Console.log("Releasing resource") ) )
return resource }))
Effect.runPromise(program).then(console.log)// Output:// Inside scoped context// Acquiring resource// resource// Releasing resource// Manual finalizerSignature
declare const scopedWith: <A, E, R>(f: (scope: Scope) => Effect<A, E, R>) => Effect<A, E, R>Since v3.11.0
running
Section titled “running”RunOptions (interface)
Section titled “RunOptions (interface)”Configuration options for running Effect programs, providing control over interruption and scheduling behavior.
When to use
Use to pass cancellation, scheduler, interruptibility, and fiber-start hooks
when running an Effect at a program boundary.
Details
signal interrupts the fiber, scheduler provides the scheduler service,
uninterruptible starts the fiber uninterruptibly, and onFiberStart
receives the created fiber.
See
runForkfor starting a fiber with these optionsrunCallbackfor callback-based running with these optionsrunPromisefor promise-based running with these optionsrunPromiseExitfor promise-based running that returns anExit
Signature
export interface RunOptions { readonly signal?: AbortSignal | undefined readonly scheduler?: Scheduler | undefined readonly uninterruptible?: boolean | undefined readonly onFiberStart?: ((fiber: Fiber<unknown, unknown>) => void) | undefined}Since v4.0.0
runCallback
Section titled “runCallback”Runs an effect asynchronously, registering onExit as a fiber observer and
returning an interruptor.
Details
The interruptor calls fiber.interruptUnsafe with the optional interruptor
id.
Example (Running with a callback)
import { Console, Effect, Exit } from "effect"
const program = Effect.gen(function* () { yield* Console.log("working") return "done"})
const interrupt = Effect.runCallback(program, { onExit: (exit) => { Effect.runSync( Exit.match(exit, { onFailure: () => Console.log("failed"), onSuccess: (value) => Console.log(`success: ${value}`) }) ) }})
// Output:// working// success: done
// interrupt() to cancel the fiber if neededSignature
declare const runCallback: <A, E>( effect: Effect<A, E, never>, options?: (RunOptions & { readonly onExit: (exit: Exit.Exit<A, E>) => void }) | undefined) => (interruptor?: number | undefined) => voidSince v2.0.0
runCallbackWith
Section titled “runCallbackWith”Forks an effect with the provided services, registers onExit as a fiber observer, and returns an interruptor.
When to use
Use when embedding an effect into callback-style code with explicit services and a synchronous interruptor.
Details
The returned interruptor calls fiber.interruptUnsafe, optionally with an interruptor id.
Example (Running with services and a callback)
import { Console, Context, Effect, Exit } from "effect"
interface Logger { log: (message: string) => Effect.Effect<void>}
const Logger = Context.Service<Logger>("Logger")
const services = Context.make(Logger, { log: (message) => Console.log(message)})
const program = Effect.gen(function* () { const logger = yield* Logger yield* logger.log("Started") return "done"})
const interrupt = Effect.runCallbackWith(services)(program, { onExit: (exit) => { if (Exit.isFailure(exit)) { // handle failure or interruption } }})
// Use the interruptor if you need to cancel the fiber later.interrupt()Signature
declare const runCallbackWith: <R>( context: Context.Context<R>) => <A, E>( effect: Effect<A, E, R>, options?: (RunOptions & { readonly onExit: (exit: Exit.Exit<A, E>) => void }) | undefined) => (interruptor?: number | undefined) => voidSince v4.0.0
runFork
Section titled “runFork”Runs an effect in the background, returning a fiber that can be observed or interrupted.
When to use
Use when you need to start an effect in the background and receive a fiber.
Example (Running an effect in the background)
import { Console, Effect, Fiber, Schedule } 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)Signature
declare const runFork: <A, E>(effect: Effect<A, E, never>, options?: RunOptions | undefined) => Fiber<A, E>Since v2.0.0
runForkWith
Section titled “runForkWith”Runs an effect in the background with the provided services.
When to use
Use when an effect still requires services, you already have a Context, and
you want a background fiber.
Example (Running with services in the background)
import { Context, Effect } from "effect"
interface Logger { log: (message: string) => void}
const Logger = Context.Service<Logger>("Logger")
const services = Context.make(Logger, { log: (message) => console.log(message)})
const program = Effect.gen(function* () { const logger = yield* Logger logger.log("Hello from service!") return "done"})
const fiber = Effect.runForkWith(services)(program)Signature
declare const runForkWith: <R>( context: Context.Context<R>) => <A, E>(effect: Effect<A, E, R>, options?: RunOptions | undefined) => Fiber<A, E>Since v4.0.0
runPromise
Section titled “runPromise”Executes an effect and returns the result as a Promise.
When to use
Use 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.
Example (Running a successful effect as a Promise)
import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1Example (Running effects as promises)
//Example: Handling a Failing Effect as a Rejected Promiseimport { Effect } from "effect"
Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my errorSee
runPromiseExitfor a version that returns anExittype instead of rejecting.
Signature
declare const runPromise: <A, E>(effect: Effect<A, E>, options?: RunOptions | undefined) => Promise<A>Since v2.0.0
runPromiseExit
Section titled “runPromiseExit”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 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. Successful effects are
wrapped in Success, and failed effects are wrapped in Failure with a
Cause.
Example (Observing promise results as Exit)
import { Effect } from "effect"
// Execute a successful effect and get the Exit result as a PromiseEffect.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 PromiseEffect.runPromiseExit(Effect.fail("my error")).then(console.log)// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }See
runPromisefor a version that rejects on failure.
Signature
declare const runPromiseExit: <A, E>(effect: Effect<A, E>, options?: RunOptions | undefined) => Promise<Exit.Exit<A, E>>Since v2.0.0
runPromiseExitWith
Section titled “runPromiseExitWith”Runs an effect and returns a Promise of Exit with provided services.
When to use
Use when you already have a Context and need Promise interop that preserves
success and failure as an Exit.
Example (Running with services as an Exit promise)
import { Context, Effect, Exit } from "effect"
interface Database { query: (sql: string) => string}
const Database = Context.Service<Database>("Database")
const services = Context.make(Database, { query: (sql) => `Result for: ${sql}`})
const program = Effect.gen(function* () { const db = yield* Database return db.query("SELECT * FROM users")})
Effect.runPromiseExitWith(services)(program).then((exit) => { if (Exit.isSuccess(exit)) { console.log("Success:", exit.value) }})Signature
declare const runPromiseExitWith: <R>( context: Context.Context<R>) => <A, E>(effect: Effect<A, E, R>, options?: RunOptions | undefined) => Promise<Exit.Exit<A, E>>Since v4.0.0
runPromiseWith
Section titled “runPromiseWith”Executes an effect as a Promise with the provided services.
When to use
Use when you already have a Context and need Promise interop that rejects on
effect failure.
Example (Running with services as a promise)
import { Context, Effect } from "effect"
interface Config { apiUrl: string}
const Config = Context.Service<Config>("Config")
const context = Context.make(Config, { apiUrl: "https://api.example.com"})
const program = Effect.gen(function* () { const config = yield* Config return `Connecting to ${config.apiUrl}`})
Effect.runPromiseWith(context)(program).then(console.log)Signature
declare const runPromiseWith: <R>( context: Context.Context<R>) => <A, E>(effect: Effect<A, E, R>, options?: RunOptions | undefined) => Promise<A>Since v4.0.0
runSync
Section titled “runSync”Executes an effect synchronously and returns its success value.
When to use
Use when you need to execute an effect that is guaranteed to complete synchronously.
Details
If the effect fails, dies, is interrupted, or performs asynchronous work,
runSync throws a FiberFailure instead of returning a value. Use
runSyncExit when you want the failure captured as an Exit.
Example (Running a synchronous effect)
import { Effect } from "effect"
const program = Effect.sync(() => { console.log("Hello, World!") return 1})
const result = Effect.runSync(program)// Output: Hello, World!
console.log(result)// Output: 1Example (Throwing for failed or async effects)
import { Effect } from "effect"
try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error
try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async workSee
runSyncExitfor a version that returns anExittype instead of throwing an error.
Signature
declare const runSync: <A, E>(effect: Effect<A, E>) => ASince v2.0.0
runSyncExit
Section titled “runSyncExit”Runs an effect synchronously and captures the outcome safely as an Exit type, which
represents the outcome (success or failure) of the effect.
When to use
Use to find out whether an effect succeeded or failed, including any defects, without dealing with asynchronous operations.
Details
The Exit type represents the result of the effect. Successful effects are
wrapped in Success, and failed effects are wrapped in Failure with a
Cause.
If the effect contains asynchronous operations, runSyncExit will
return an Failure with a Die cause, indicating that the effect cannot be
resolved synchronously.
Example (Observing synchronous results as Exit)
import { Effect } from "effect"
console.log(Effect.runSyncExit(Effect.succeed(1)))// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// }
console.log(Effect.runSyncExit(Effect.fail("my error")))// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }Example (Capturing async work as a Die cause)
import { Effect } from "effect"
console.log(Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))))// Output:// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// _tag: 'Die',// defect: [Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work] {// fiber: [FiberRuntime],// _tag: 'AsyncFiberException',// name: 'AsyncFiberException'// }// }// }See
runSyncfor a version that throws on failure.
Signature
declare const runSyncExit: <A, E>(effect: Effect<A, E>) => Exit.Exit<A, E>Since v2.0.0
runSyncExitWith
Section titled “runSyncExitWith”Runs an effect synchronously with provided services, returning an Exit result safely.
When to use
Use when you already have a Context and need a synchronous Exit instead of
throwing on failure.
Example (Running synchronously with services as Exit)
import { Context, Effect, Exit } from "effect"
// Define a logger serviceconst Logger = Context.Service<{ log: (msg: string) => void}>("Logger")
const program = Effect.gen(function* () { const logger = yield* Effect.service(Logger) logger.log("Computing result...") return 42})
// Prepare contextconst context = Context.make(Logger, { log: (msg) => console.log(`[LOG] ${msg}`)})
const exit = Effect.runSyncExitWith(context)(program)
if (Exit.isSuccess(exit)) { console.log(`Success: ${exit.value}`)} else { console.log(`Failure: ${exit.cause}`)}// Output:// [LOG] Computing result...// Success: 42Signature
declare const runSyncExitWith: <R>(context: Context.Context<R>) => <A, E>(effect: Effect<A, E, R>) => Exit.Exit<A, E>Since v4.0.0
runSyncWith
Section titled “runSyncWith”Executes an effect synchronously with provided services.
When to use
Use when you already have a Context, the effect is known to complete
synchronously, and failures should throw.
Example (Running synchronously with services)
import { Context, Effect } from "effect"
interface MathService { add: (a: number, b: number) => number}
const MathService = Context.Service<MathService>("MathService")
const context = Context.make(MathService, { add: (a, b) => a + b})
const program = Effect.gen(function* () { const math = yield* MathService return math.add(2, 3)})
const result = Effect.runSyncWith(context)(program)console.log(result) // 5Signature
declare const runSyncWith: <R>(context: Context.Context<R>) => <A, E>(effect: Effect<A, E, R>) => ASince v4.0.0
sequencing
Section titled “sequencing”andThen
Section titled “andThen”Runs this effect and then runs another effect, optionally using the first effect’s success value to choose the next effect.
When to use
Use when you need one effect to run after another and the second effect may depend on the first effect’s success value.
Details
When the second argument is an Effect, the first success value is discarded
and the returned effect produces the second effect’s value. When the second
argument is a function, it receives the first success value and must return
the next Effect.
Failures or requirements from either effect are preserved in the returned effect.
Example (Choosing andThen syntax variants)
import { Effect, pipe } from "effect"
const myEffect = Effect.succeed(1)const anotherEffect = Effect.succeed("done")
const transformedWithPipe = pipe(myEffect, Effect.andThen(anotherEffect))const transformedWithDataFirst = Effect.andThen(myEffect, anotherEffect)const transformedWithMethod = myEffect.pipe(Effect.andThen(anotherEffect))Example (Sequencing a discount calculation after fetching a total)
import { Data, Effect, pipe } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
// Function to apply a discount safely to a transaction amountconst applyDiscount = (total: number, discountRate: number): Effect.Effect<number, DiscountRateError> => discountRate === 0 ? Effect.fail(new DiscountRateError()) : Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from databaseconst fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Using Effect.map and Effect.flatMapconst result1 = pipe( fetchTransactionAmount, Effect.map((amount) => amount * 2), Effect.flatMap((amount) => applyDiscount(amount, 5)))
Effect.runPromise(result1).then(console.log)// Output: 190
// Using Effect.andThenconst result2 = pipe( fetchTransactionAmount, Effect.andThen((amount) => Effect.succeed(amount * 2)), Effect.andThen((amount) => applyDiscount(amount, 5)))
Effect.runPromise(result2).then(console.log)// Output: 190Signature
declare const andThen: { <A, B, E2, R2>(f: (a: A) => Effect<B, E2, R2>): <E, R>(self: Effect<A, E, R>) => Effect<B, E | E2, R | R2> <B, E2, R2>(f: Effect<B, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<B, E | E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: (a: A) => Effect<B, E2, R2>): Effect<B, E | E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: Effect<B, E2, R2>): Effect<B, E | E2, R | R2>}Since v2.0.0
flatMap
Section titled “flatMap”Chains effects to produce new Effect instances, useful for combining
operations that depend on previous results.
When to use
Use when you need to chain multiple effects, ensuring that each
step produces a new Effect while flattening any nested effects that may
occur.
Details
flatMap lets you sequence effects so that the result of one effect can be
used in the next step. It is similar to flatMap used with arrays but works
specifically with Effect instances, allowing you to avoid deeply nested
effect structures.
Since effects are immutable, flatMap always returns a new effect instead of
changing the original one.
Example (Choosing flatMap syntax variants)
import { Effect, pipe } from "effect"
const myEffect = Effect.succeed(1)const transformation = (n: number) => Effect.succeed(n + 1)
const flatMappedWithPipe = pipe(myEffect, Effect.flatMap(transformation))const flatMappedWithDataFirst = Effect.flatMap(myEffect, transformation)const flatMappedWithMethod = myEffect.pipe(Effect.flatMap(transformation))Example (Sequencing dependent effects)
import { Data, Effect, pipe } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
// Function to apply a discount safely to a transaction amountconst applyDiscount = (total: number, discountRate: number): Effect.Effect<number, DiscountRateError> => discountRate === 0 ? Effect.fail(new DiscountRateError()) : Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from databaseconst fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Chaining the fetch and discount application using `flatMap`const finalAmount = pipe( fetchTransactionAmount, Effect.flatMap((amount) => applyDiscount(amount, 5)))
Effect.runPromise(finalAmount).then(console.log)// Output: 95See
tapfor a version that ignores the result of the effect.
Signature
declare const flatMap: { <A, B, E1, R1>(f: (a: A) => Effect<B, E1, R1>): <E, R>(self: Effect<A, E, R>) => Effect<B, E1 | E, R1 | R> <A, E, R, B, E1, R1>(self: Effect<A, E, R>, f: (a: A) => Effect<B, E1, R1>): Effect<B, E | E1, R | R1>}Since v2.0.0
flatten
Section titled “flatten”Flattens an Effect that produces another Effect into a single effect.
Example (Flattening nested effects)
import { Console, Effect } from "effect"
const nested = Effect.succeed(Effect.succeed("hello"))
const program = Effect.gen(function* () { const value = yield* Effect.flatten(nested) yield* Console.log(value) // Output: hello})Signature
declare const flatten: <A, E, R, E2, R2>(self: Effect<Effect<A, E, R>, E2, R2>) => Effect<A, E | E2, R | R2>Since v2.0.0
Runs a side effect with the result of an effect without changing the original value.
When to use
Use when you need to run an effectful observation, such as logging or tracking, while passing the original success value to the next step.
Details
tap works similarly to flatMap, but it ignores the result of the function
passed to it. The value from the previous effect remains available for the
next part of the chain. Note that if the side effect fails, the entire chain
will fail too.
Example (Logging a step in a pipeline)
import { Console, Data, Effect, pipe } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
// Function to apply a discount safely to a transaction amountconst applyDiscount = (total: number, discountRate: number): Effect.Effect<number, DiscountRateError> => discountRate === 0 ? Effect.fail(new DiscountRateError()) : Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from databaseconst fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe( fetchTransactionAmount, // Log the fetched transaction amount Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)), // `amount` is still available! Effect.flatMap((amount) => applyDiscount(amount, 5)))
Effect.runPromise(finalAmount).then(console.log)// Output:// Apply a discount to: 100// 95Signature
declare const tap: { <A, B, E2, R2>(f: (a: NoInfer<A>) => Effect<B, E2, R2>): <E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2> <B, E2, R2>(f: Effect<B, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: (a: NoInfer<A>) => Effect<B, E2, R2>): Effect<A, E | E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: Effect<B, E2, R2>): Effect<A, E | E2, R | R2>}Since v2.0.0
tapCause
Section titled “tapCause”Runs an effectful operation with the full Cause when the source effect
fails.
When to use
Use when failure observation needs typed failures, defects, and interruptions rather than only the typed error value.
Details
Use this to log or inspect typed failures, defects, and interruptions. When the operation succeeds, the original cause is preserved. If the operation fails, its error is also represented in the returned effect.
Example (Observing full failure causes)
import { Cause, Console, Effect } from "effect"
const task = Effect.fail("Something went wrong")
const program = Effect.tapCause(task, (cause) => Console.log(`Logging cause: ${Cause.squash(cause)}`))
Effect.runPromiseExit(program).then(console.log)// Output: "Logging cause: Error: Something went wrong"// Then: { _id: 'Exit', _tag: 'Failure', cause: ... }Signature
declare const tapCause: { <E, X, E2, R2>( f: (cause: Cause.Cause<NoInfer<E>>) => Effect<X, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R2 | R> <A, E, R, X, E2, R2>( self: Effect<A, E, R>, f: (cause: Cause.Cause<E>) => Effect<X, E2, R2> ): Effect<A, E | E2, R | R2>}Since v4.0.0
tapCauseFilter
Section titled “tapCauseFilter”Executes a side effect conditionally when a failed effect’s cause passes a filter.
When to use
Use when you need to observe only failure causes selected by a Filter,
while giving the side effect both the selected value and the original
Cause.
Details
A successful filter result runs the side effect with the selected value and original cause. A failed filter result skips the side effect and preserves the original cause.
See
tapCauseIffor selecting causes with a boolean predicatetapCausefor observing every failure causecatchCauseFilterfor recovering from selected causes instead of only observing them
Signature
declare const tapCauseFilter: { <E, B, E2, R2, EB, X extends Cause.Cause<any>>( filter: Filter.Filter<Cause.Cause<E>, EB, X>, f: (a: EB, cause: Cause.Cause<E>) => Effect<B, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2> <A, E, R, B, E2, R2, EB, X extends Cause.Cause<any>>( self: Effect<A, E, R>, filter: Filter.Filter<Cause.Cause<E>, EB, X>, f: (a: EB, cause: Cause.Cause<E>) => Effect<B, E2, R2> ): Effect<A, E | E2, R | R2>}Since v4.0.0
tapCauseIf
Section titled “tapCauseIf”Executes a side effect conditionally when a failed effect’s cause matches a predicate.
Details
This function allows you to tap into the cause of an effect’s failure only when the cause matches a specific predicate. This is useful for conditional logging, monitoring, or other side effects based on the type of failure.
Example (Observing selected failure causes)
import { Cause, Console, Effect } from "effect"
const task = Effect.fail("Network timeout")
// Only log causes that contain failures (not interrupts or defects)const program = Effect.tapCauseIf(task, Cause.hasFails, (cause) => Console.log(`Logging failure cause: ${Cause.squash(cause)}`))
Effect.runPromiseExit(program).then(console.log)// Output: "Logging failure cause: Network timeout"// Then: { _id: 'Exit', _tag: 'Failure', cause: ... }Signature
declare const tapCauseIf: { <E, B, E2, R2>( predicate: Predicate.Predicate<Cause.Cause<E>>, f: (cause: Cause.Cause<E>) => Effect<B, E2, R2> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2> <A, E, R, B, E2, R2>( self: Effect<A, E, R>, predicate: Predicate.Predicate<Cause.Cause<E>>, f: (cause: Cause.Cause<E>) => Effect<B, E2, R2> ): Effect<A, E | E2, R | R2>}Since v4.0.0
tapDefect
Section titled “tapDefect”Runs an effectful operation when the source effect dies with a defect.
Details
Use this for diagnostics such as logging unexpected thrown exceptions or
values passed to die. Recoverable failures are not handled. When the
operation succeeds, the original defect is preserved; if the operation fails,
its error is also represented in the returned effect.
Example (Observing defects)
import { Console, Effect } from "effect"
// Simulate a task that fails with a recoverable errorconst task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
// tapDefect won't log anything because NetworkError is not a defectconst tapping1 = Effect.tapDefect(task1, (cause) => Console.log(`defect: ${cause}`))
Effect.runFork(tapping1)// No Output
// Simulate a severe failure in the systemconst task2: Effect.Effect<number> = Effect.die("Something went wrong")
// Log the defect using tapDefectconst tapping2 = Effect.tapDefect(task2, (cause) => Console.log(`defect: ${cause}`))
Effect.runFork(tapping2)// Output:// defect: RuntimeException: Something went wrong// ... stack trace ...Signature
declare const tapDefect: { <E, B, E2, R2>(f: (defect: unknown) => Effect<B, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R | R2> <A, E, R, B, E2, R2>(self: Effect<A, E, R>, f: (defect: unknown) => Effect<B, E2, R2>): Effect<A, E | E2, R | R2>}Since v2.0.0
tapError
Section titled “tapError”Runs an effectful operation when the source effect fails, while preserving the original failure when the operation succeeds.
Details
Use this for logging, metrics, or other failure-side observations. If the
operation passed to tapError fails, that error is also represented in the
returned effect’s error channel.
Example (Running effects on failure)
import { Console, Effect } from "effect"
// Simulate a task that fails with an errorconst task: Effect.Effect<number, string> = Effect.fail("NetworkError")
// Use tapError to log the error message when the task failsconst tapping = Effect.tapError(task, (error) => Console.log(`expected error: ${error}`))
Effect.runFork(tapping)// Output:// expected error: NetworkErrorSignature
declare const tapError: { <E, X, E2, R2>(f: (e: NoInfer<E>) => Effect<X, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R2 | R> <A, E, R, X, E2, R2>(self: Effect<A, E, R>, f: (e: E) => Effect<X, E2, R2>): Effect<A, E | E2, R | R2>}Since v2.0.0
tapErrorTag
Section titled “tapErrorTag”Runs an effectful handler when a failure’s _tag matches.
Details
Use this with tagged-union errors to perform side effects for one tag or a list of tags. When the handler succeeds, the original failure is preserved; if the handler fails, its error is also included in the returned effect.
Example (Running effects for tagged failures)
import { Console, Data, Effect } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{ statusCode: number}> {}
class ValidationError extends Data.TaggedError("ValidationError")<{ field: string}> {}
const task: Effect.Effect<number, NetworkError | ValidationError> = Effect.fail(new NetworkError({ statusCode: 504 }))
const program = Effect.tapErrorTag(task, "NetworkError", (error) => Console.log(`expected error: ${error.statusCode}`))
Effect.runPromiseExit(program)// Output:// expected error: 504Signature
declare const tapErrorTag: { <const K extends Tags<E> | Arr.NonEmptyReadonlyArray<Tags<E>>, E, A1, E1, R1>( k: K, f: (e: ExtractTag<NoInfer<E>, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K>) => Effect<A1, E1, R1> ): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E1, R1 | R> <A, E, R, const K extends Tags<E> | Arr.NonEmptyReadonlyArray<Tags<E>>, R1, E1, A1>( self: Effect<A, E, R>, k: K, f: (e: ExtractTag<E, K extends Arr.NonEmptyReadonlyArray<string> ? K[number] : K>) => Effect<A1, E1, R1> ): Effect<A, E | E1, R | R1>}Since v2.0.0
supervision & fibers
Section titled “supervision & fibers”awaitAllChildren
Section titled “awaitAllChildren”Waits for all child fibers forked by this effect to complete before this effect completes.
When to use
Use to let an effect start child work concurrently while still delaying its own completion until that child work is done.
Gotchas
Child fibers that already exist before the wrapped effect starts are not awaited.
See
forkChildfor forking child fibers that are awaited by this operatorforkDetachfor forking fibers outside the child scopeforkInfor forking into an explicit scopeforkScopedfor forking fibers tied to the current scope
Signature
declare const awaitAllChildren: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Since v2.0.0
Accesses the fiber currently executing the effect.
Example (Accessing the current fiber)
import { Console, Effect } from "effect"
const program = Effect.gen(function* () { const fiber = yield* Effect.fiber yield* Console.log(`Fiber id: ${fiber.id}`)})Signature
declare const fiber: Effect<Fiber<unknown, unknown>, never, never>Since v4.0.0
fiberId
Section titled “fiberId”Accesses the current fiber id executing the effect.
Example (Accessing the current fiber id)
import { Effect } from "effect"
const program = Effect.log("event").pipe( // Read the current span with the fiber id for tagging. Effect.andThen(Effect.all([Effect.currentSpan, Effect.fiberId])), Effect.withSpan("A"), Effect.map(([span, fiberId]) => ({ spanName: span.name, fiberId })))Signature
declare const fiberId: Effect<number, never, never>Since v2.0.0
forkChild
Section titled “forkChild”Returns an effect that forks this effect into its own separate fiber, returning the fiber immediately, without waiting for it to begin executing the effect.
Details
You can use the forkChild method whenever you want to execute an effect in a
new fiber, concurrently and without “blocking” the fiber executing other
effects. Using fibers can be tricky, so instead of using this method
directly, consider other higher-level methods, such as raceWith,
zipPar, and so forth.
The fiber returned by this method has methods to interrupt the fiber and to
wait for it to finish executing the effect. See Fiber for more
information.
Whenever you use this method to launch a new fiber, the new fiber is
attached to the parent fiber’s scope. This means when the parent fiber
terminates, the child fiber will be terminated as well, ensuring that no
fibers leak. This behavior is called “auto supervision”, and if this
behavior is not desired, you may use the forkDetach or forkIn methods.
Example (Forking a child fiber)
import { Effect, Fiber } from "effect"
const longRunningTask = Effect.gen(function* () { yield* Effect.sleep("2 seconds") yield* Effect.log("Task completed") return "result"})
const program = Effect.gen(function* () { const fiber = yield* longRunningTask.pipe(Effect.forkChild)
// or fork a fiber that starts immediately: yield* longRunningTask.pipe(Effect.forkChild({ startImmediately: true }))
yield* Effect.log("Task forked, continuing...") const result = yield* Fiber.join(fiber) return result})Signature
declare const forkChild: < Arg extends | Effect<any, any, any> | { readonly startImmediately?: boolean | undefined; readonly uninterruptible?: boolean | "inherit" | undefined } | undefined = { readonly startImmediately?: boolean | undefined readonly uninterruptible?: boolean | "inherit" | undefined }>( effectOrOptions?: Arg, options?: | { readonly startImmediately?: boolean | undefined; readonly uninterruptible?: boolean | "inherit" | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Effect<Fiber<_A, _E>, never, _R> : <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber<A, E>, never, R>Since v4.0.0
forkDetach
Section titled “forkDetach”Forks the effect into a new fiber attached to the global scope. Because the new fiber is attached to the global scope, when the fiber executing the returned effect terminates, the forked fiber will continue running.
Example (Forking a detached fiber)
import { Effect } from "effect"
const daemonTask = Effect.gen(function* () { while (true) { yield* Effect.sleep("1 second") yield* Effect.log("Daemon running...") }})
const program = Effect.gen(function* () { const fiber = yield* daemonTask.pipe(Effect.forkDetach)
// or fork a fiber that starts immediately: yield* daemonTask.pipe(Effect.forkDetach({ startImmediately: true }))
yield* Effect.log("Daemon started") yield* Effect.sleep("3 seconds") // Daemon continues running after this effect completes return "main completed"})Signature
declare const forkDetach: < Arg extends | Effect<any, any, any> | { readonly startImmediately?: boolean | undefined; readonly uninterruptible?: boolean | "inherit" | undefined } | undefined = { readonly startImmediately?: boolean | undefined readonly uninterruptible?: boolean | "inherit" | undefined }>( effectOrOptions?: Arg, options?: | { readonly startImmediately?: boolean | undefined; readonly uninterruptible?: boolean | "inherit" | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Effect<Fiber<_A, _E>, never, _R> : <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber<A, E>, never, R>Since v4.0.0
forkIn
Section titled “forkIn”Forks the effect in the specified scope. The fiber will be interrupted when the scope is closed.
Example (Forking into a supplied scope)
import { Effect } from "effect"
const task = Effect.gen(function* () { yield* Effect.sleep("10 seconds") return "completed"})
const program = Effect.scoped( Effect.gen(function* () { const scope = yield* Effect.scope const fiber = yield* Effect.forkIn(task, scope) yield* Effect.sleep("1 second") // Fiber will be interrupted when scope closes return "done" }))Signature
declare const forkIn: { ( scope: Scope, options?: { readonly startImmediately?: boolean | undefined readonly uninterruptible?: boolean | "inherit" | undefined } ): <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber<A, E>, never, R> <A, E, R>( self: Effect<A, E, R>, scope: Scope, options?: { readonly startImmediately?: boolean | undefined readonly uninterruptible?: boolean | "inherit" | undefined } ): Effect<Fiber<A, E>, never, R>}Since v2.0.0
forkScoped
Section titled “forkScoped”Forks the fiber in a Scope, interrupting it when the scope is closed.
Example (Forking into the current scope)
import { Effect } from "effect"
const backgroundTask = Effect.gen(function* () { yield* Effect.sleep("5 seconds") yield* Effect.log("Background task completed") return "result"})
const program = Effect.scoped( Effect.gen(function* () { const fiber = yield* backgroundTask.pipe(Effect.forkScoped)
// or fork a fiber that starts immediately: yield* backgroundTask.pipe(Effect.forkScoped({ startImmediately: true }))
yield* Effect.log("Task forked in scope") yield* Effect.sleep("1 second")
// Fiber will be interrupted when scope closes return "scope completed" }))Signature
declare const forkScoped: < Arg extends | Effect<any, any, any> | { readonly startImmediately?: boolean | undefined; readonly uninterruptible?: boolean | "inherit" | undefined } | undefined = { readonly startImmediately?: boolean | undefined readonly uninterruptible?: boolean | "inherit" | undefined }>( effectOrOptions?: Arg, options?: | { readonly startImmediately?: boolean | undefined; readonly uninterruptible?: boolean | "inherit" | undefined } | undefined) => [Arg] extends [Effect<infer _A, infer _E, infer _R>] ? Effect<Fiber<_A, _E>, never, _R | Scope> : <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber<A, E>, never, R | Scope>Since v2.0.0
tracing
Section titled “tracing”annotateCurrentSpan
Section titled “annotateCurrentSpan”Adds an annotation to the current span if available.
Example (Annotating the current span)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.annotateCurrentSpan("userId", "123") yield* Effect.annotateCurrentSpan({ operation: "user-lookup", timestamp: Date.now() }) yield* Effect.log("User lookup completed") return "success"})
const traced = Effect.withSpan(program, "user-operation")Signature
declare const annotateCurrentSpan: { (key: string, value: unknown): Effect<void> (values: Record<string, unknown>): Effect<void>}Since v2.0.0
annotateSpans
Section titled “annotateSpans”Adds an annotation to each span in this effect.
Example (Annotating all spans)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.log("Doing some work...") return "result"})
// Add single annotationconst annotated1 = Effect.annotateSpans(program, "user", "john")
// Add multiple annotationsconst annotated2 = Effect.annotateSpans(program, { operation: "data-processing", version: "1.0.0", environment: "production"})Signature
declare const annotateSpans: { (key: string, value: unknown): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R> (values: Record<string, unknown>): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>(effect: Effect<A, E, R>, key: string, value: unknown): Effect<A, E, R> <A, E, R>(effect: Effect<A, E, R>, values: Record<string, unknown>): Effect<A, E, R>}Since v2.0.0
currentParentSpan
Section titled “currentParentSpan”Returns the current parent span from the effect context.
Details
The effect succeeds with either a local span or external span when one is
present, and fails with NoSuchElementError when no parent span is
available.
Example (Reading the parent span)
import { Effect } from "effect"
const childOperation = Effect.gen(function* () { const parentSpan = yield* Effect.currentParentSpan yield* Effect.log(`Parent span: ${parentSpan}`) return "child completed"})
const program = Effect.gen(function* () { yield* Effect.withSpan(childOperation, "child-span") return "parent completed"})
const traced = Effect.withSpan(program, "parent-span")Signature
declare const currentParentSpan: Effect<AnySpan, Cause.NoSuchElementError, never>Since v2.0.0
currentSpan
Section titled “currentSpan”Returns the currently active local tracing span.
Details
The effect fails with NoSuchElementError when there is no active local
Span.
Example (Reading the current span)
import { Effect } from "effect"
const program = Effect.gen(function* () { const span = yield* Effect.currentSpan yield* Effect.log(`Current span: ${span}`) return "done"})
const traced = Effect.withSpan(program, "my-span")Signature
declare const currentSpan: Effect<Span, Cause.NoSuchElementError, never>Since v2.0.0
linkSpans
Section titled “linkSpans”Adds a link with the provided span to all spans in this effect.
Details
This is useful for connecting spans that are related but not in a direct parent-child relationship. For example, you might want to link spans from parallel operations or connect spans across different traces.
Example (Linking one span to another span)
import { Effect } from "effect"
const parentEffect = Effect.withSpan("parent-operation")(Effect.succeed("parent result"))
const childEffect = Effect.withSpan("child-operation")(Effect.succeed("child result"))
// Link the child span to the parent spanconst program = Effect.gen(function* () { const parentSpan = yield* Effect.currentSpan const result = yield* childEffect.pipe(Effect.linkSpans(parentSpan, { relationship: "follows" })) return result})Example (Linking multiple spans at once)
import { Effect } from "effect"
// Link multiple spansconst program = Effect.gen(function* () { const span1 = yield* Effect.currentSpan const span2 = yield* Effect.currentSpan
return yield* Effect.succeed("result").pipe( Effect.linkSpans([span1, span2], { type: "dependency", source: "multiple-operations" }) )})Signature
declare const linkSpans: { ( span: AnySpan | ReadonlyArray<AnySpan>, attributes?: Record<string, unknown> ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>( self: Effect<A, E, R>, span: AnySpan | ReadonlyArray<AnySpan>, attributes?: Record<string, unknown> ): Effect<A, E, R>}Since v2.0.0
makeSpan
Section titled “makeSpan”Creates a new tracing span and returns it without managing its lifetime.
Details
The span is not added to the current span stack and is not ended
automatically. Use withSpan, useSpan, or makeSpanScoped when the span
should be installed as context or closed automatically.
Example (Creating a span manually)
import { Effect } from "effect"
const program = Effect.gen(function* () { const span = yield* Effect.makeSpan("my-operation") yield* Effect.log("Operation in progress") return "completed"})Signature
declare const makeSpan: (name: string, options?: SpanOptionsNoTrace) => Effect<Span>Since v2.0.0
makeSpanScoped
Section titled “makeSpanScoped”Create a new span for tracing, and automatically close it when the Scope finalizes.
Details
The span is not added to the current span stack, so no child spans will be created for it.
Example (Creating a scoped standalone span)
import { Effect } from "effect"
const program = Effect.scoped( Effect.gen(function* () { const span = yield* Effect.makeSpanScoped("scoped-operation") yield* Effect.log("Working...") return "done" // Span automatically closes when scope ends }))Signature
declare const makeSpanScoped: (name: string, options?: SpanOptionsNoTrace | undefined) => Effect<Span, never, Scope>Since v2.0.0
spanAnnotations
Section titled “spanAnnotations”Returns the tracing span annotations currently carried in the effect context.
Details
These annotations are applied to spans created inside the context, such as
spans created by withSpan, useSpan, or makeSpan.
Example (Providing span annotations)
import { Effect } from "effect"
const program = Effect.gen(function* () { // Add some annotations to the current span yield* Effect.annotateCurrentSpan("userId", "123") yield* Effect.annotateCurrentSpan("operation", "data-processing")
// Retrieve all annotations const annotations = yield* Effect.spanAnnotations
console.log("Current span annotations:", annotations) return annotations})
Effect.runPromise(program).then(console.log)// Output: Current span annotations: { userId: "123", operation: "data-processing" }Signature
declare const spanAnnotations: Effect<Readonly<Record<string, unknown>>, never, never>Since v2.0.0
spanLinks
Section titled “spanLinks”Returns the tracing span links currently carried in the effect context.
Details
These links are attached to spans created inside the context. Span links connect related spans without making one span the parent of another.
Example (Providing span links)
import { Effect } from "effect"
const program = Effect.gen(function* () { // Get the current span links const links = yield* Effect.spanLinks console.log(`Current span has ${links.length} links`) return links})Signature
declare const spanLinks: Effect<ReadonlyArray<SpanLink>, never, never>Since v2.0.0
tracer
Section titled “tracer”Returns the current tracer from the context.
Example (Accessing the current tracer)
import { Effect } from "effect"
const program = Effect.gen(function* () { const currentTracer = yield* Effect.tracer yield* Effect.log(`Using tracer: ${currentTracer}`) return "operation completed"})Signature
declare const tracer: Effect<Tracer, never, never>Since v2.0.0
useSpan
Section titled “useSpan”Create a new span for tracing, and automatically close it when the effect completes.
Details
The span is not added to the current span stack, so no child spans will be created for it.
Example (Running an effect with a standalone span)
import { Effect } from "effect"
const program = Effect.useSpan("user-operation", (span) => Effect.gen(function* () { yield* Effect.log("Processing user data") return "success" }))Signature
declare const useSpan: { <A, E, R>(name: string, evaluate: (span: Span) => Effect<A, E, R>): Effect<A, E, R> <A, E, R>(name: string, options: SpanOptionsNoTrace, evaluate: (span: Span) => Effect<A, E, R>): Effect<A, E, R>}Since v2.0.0
withParentSpan
Section titled “withParentSpan”Adds the provided span to the current span stack.
Example (Setting a parent span)
import { Effect } from "effect"
const program = Effect.gen(function* () { const span = yield* Effect.makeSpan("parent-span") const childTask = Effect.log("Child operation") yield* Effect.withParentSpan(childTask, span) return "completed"})Signature
declare const withParentSpan: { (value: AnySpan, options?: TraceOptions): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, ParentSpan>> <A, E, R>(self: Effect<A, E, R>, value: AnySpan, options?: TraceOptions): Effect<A, E, Exclude<R, ParentSpan>>}Since v2.0.0
withSpan
Section titled “withSpan”Wraps the effect with a child span for tracing.
Example (Wrapping an effect in a child span)
import { Effect } from "effect"
const task = Effect.gen(function* () { yield* Effect.log("Executing task") return "result"})
const traced = Effect.withSpan(task, "my-task", { attributes: { version: "1.0" }})Signature
declare const withSpan: { <Args extends ReadonlyArray<any>>( name: string, options?: SpanOptionsNoTrace | ((...args: NoInfer<Args>) => SpanOptionsNoTrace) | undefined, traceOptions?: TraceOptions | undefined ): <A, E, R>(self: Effect<A, E, R>, ...args: Args) => Effect<A, E, Exclude<R, ParentSpan>> <A, E, R>( self: Effect<A, E, R>, name: string, options?: SpanOptions | undefined ): Effect<A, E, Exclude<R, ParentSpan>>}Since v2.0.0
withSpanScoped
Section titled “withSpanScoped”Wraps the effect with a scoped child span for tracing.
Details
The span is ended when the Scope is finalized.
Example (Creating a scoped child span)
import { Effect } from "effect"
const program = Effect.scoped( Effect.gen(function* () { const task = Effect.log("Working...") yield* Effect.withSpanScoped(task, "scoped-task") return "completed" }))Signature
declare const withSpanScoped: { ( name: string, options?: SpanOptions ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, ParentSpan> | Scope> <A, E, R>(self: Effect<A, E, R>, name: string, options?: SpanOptions): Effect<A, E, Exclude<R, ParentSpan> | Scope>}Since v2.0.0
withTracer
Section titled “withTracer”Provides a tracer to an effect.
Example (Providing a tracer)
import { Effect } from "effect"
const program = Effect.gen(function* () { yield* Effect.log("Using tracer") return "completed"})
// withTracer provides a tracer to the effect context// const traced = Effect.withTracer(program, customTracer)Signature
declare const withTracer: { (value: Tracer): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>(effect: Effect<A, E, R>, value: Tracer): Effect<A, E, R>}Since v2.0.0
withTracerEnabled
Section titled “withTracerEnabled”Enables or disables tracing for spans created by the given effect.
Details
When enabled is false, spans created inside the effect are not registered
with the current tracer and do not propagate as normal trace parents.
Example (Enabling or disabling tracing)
import { Effect } from "effect"
Effect.succeed(42).pipe( Effect.withSpan("my-span"), // the span will not be registered with the tracer Effect.withTracerEnabled(false))Signature
declare const withTracerEnabled: { (enabled: boolean): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>(effect: Effect<A, E, R>, enabled: boolean): Effect<A, E, R>}Since v2.0.0
withTracerTiming
Section titled “withTracerTiming”Enables or disables tracer timing for the given Effect.
Example (Enabling or disabling tracing timing)
import { Effect } from "effect"
Effect.succeed(42).pipe( Effect.withSpan("my-span"), // the span will not have timing information Effect.withTracerTiming(false))Signature
declare const withTracerTiming: { (enabled: boolean): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R> <A, E, R>(effect: Effect<A, E, R>, enabled: boolean): Effect<A, E, R>}Since v2.0.0
tracking
Section titled “tracking”Updates the Metric every time the Effect is executed.
Details
Also accepts an optional function which can be used to map the Exit value
of the Effect into a valid Input for the Metric.
Example (Incrementing a metric for each execution)
import { Effect, Metric } from "effect"
const counter = Metric.counter("effect_executions", { description: "Counts effect executions"}).pipe(Metric.withConstantInput(1))
const program = Effect.succeed("Hello").pipe(Effect.track(counter))
// This will increment the counter by 1 when executedEffect.runPromise(program).then( () => Effect.runPromise(Metric.value(counter)).then(console.log) // Output: { count: 1, incremental: false })Example (Mapping exits before updating a metric)
import { Effect, Exit, Metric } from "effect"
// Track different exit types with custom mappingconst exitTracker = Metric.frequency("exit_types", { description: "Tracks success/failure/defect counts"})
const mapExitToString = (exit: Exit.Exit<string, Error>) => { if (Exit.isSuccess(exit)) return "success" if (Exit.isFailure(exit)) return "failure" return "defect"}
const effect = Effect.succeed("result").pipe(Effect.track(exitTracker, mapExitToString))Signature
declare const track: { <Input, State, E, A>( metric: Metric.Metric<Input, State>, f: (exit: Exit.Exit<A, E>) => Input ): <E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <State, E, A>( metric: Metric.Metric<Exit.Exit<NoInfer<A>, NoInfer<E>>, State> ): <R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R, Input, State>( self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (exit: Exit.Exit<A, E>) => Input ): Effect<A, E, R> <A, E, R, State>( self: Effect<A, E, R>, metric: Metric.Metric<Exit.Exit<NoInfer<A>, NoInfer<E>>, State> ): Effect<A, E, R>}Since v4.0.0
trackDefects
Section titled “trackDefects”Updates the provided Metric every time the wrapped Effect fails with an
unexpected error (i.e. a defect).
Details
Also accepts an optional function which can be used to map the defect value
of the Effect into a valid Input for the Metric.
Example (Counting defects)
import { Effect, Metric } from "effect"
const defectCounter = Metric.counter("defects").pipe(Metric.withConstantInput(1))
const program = Effect.die("Critical system failure").pipe(Effect.trackDefects(defectCounter))
Effect.runPromiseExit(program).then( () => Effect.runPromise(Metric.value(defectCounter)).then(console.log) // Output: { count: 1, incremental: false })Example (Mapping defects before tracking)
import { Effect, Metric } from "effect"
// Track defect types using frequency metricconst defectTypeFrequency = Metric.frequency("defect_types")
const program = Effect.die(new Error("Null pointer exception")).pipe( Effect.trackDefects(defectTypeFrequency, (defect: unknown) => { if (defect instanceof Error) return defect.constructor.name return typeof defect }))
Effect.runPromiseExit(program).then( () => Effect.runPromise(Metric.value(defectTypeFrequency)).then(console.log) // Output: { occurrences: Map(1) { "Error" => 1 } })Signature
declare const trackDefects: { <Input, State>( metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <State, E>(metric: Metric.Metric<unknown, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R, Input, State>( self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input ): Effect<A, E, R> <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>}Since v4.0.0
trackDuration
Section titled “trackDuration”Updates the provided Metric with the Duration of time (in nanoseconds)
that the wrapped Effect took to complete.
Details
Also accepts an optional function which can be used to map the Duration
that the wrapped Effect took to complete into a valid Input for the
Metric.
Example (Recording execution duration)
import { Effect, Metric } from "effect"
const executionTimer = Metric.timer("execution_time")
const program = Effect.sleep("100 millis").pipe(Effect.trackDuration(executionTimer))
Effect.runPromise(program).then( () => Effect.runPromise(Metric.value(executionTimer)).then(console.log) // Output: { count: 1, min: 100000000, max: 100000000, sum: 100000000 })Example (Mapping duration before tracking)
import { Duration, Effect, Metric } from "effect"
// Track execution time in milliseconds using custom mappingconst durationGauge = Metric.gauge("execution_millis")
const program = Effect.sleep("200 millis").pipe( Effect.trackDuration(durationGauge, (duration) => Duration.toMillis(duration)))
Effect.runPromise(program).then( () => Effect.runPromise(Metric.value(durationGauge)).then(console.log) // Output: { value: 200 })Signature
declare const trackDuration: { <Input, State>( metric: Metric.Metric<Input, State>, f: (duration: Duration.Duration) => Input ): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <State, E>(metric: Metric.Metric<Duration.Duration, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R, Input, State>( self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (duration: Duration.Duration) => Input ): Effect<A, E, R> <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<Duration.Duration, State>): Effect<A, E, R>}Since v4.0.0
trackErrors
Section titled “trackErrors”Updates the provided Metric every time the wrapped Effect fails with an
expected error.
Details
Also accepts an optional function which can be used to map the error value
of the Effect into a valid Input for the Metric.
Example (Counting expected failures)
import { Effect, Metric } from "effect"
const errorCounter = Metric.counter("errors").pipe(Metric.withConstantInput(1))
const program = Effect.fail("Network timeout").pipe(Effect.trackErrors(errorCounter))
Effect.runPromiseExit(program).then( () => Effect.runPromise(Metric.value(errorCounter)).then(console.log) // Output: { count: 1, incremental: false })Example (Mapping errors before tracking)
import { Data, Effect, Metric } from "effect"
class ConnectionFailedError extends Data.TaggedError("ConnectionFailedError")<{}> {}
// Track error types using frequency metricconst errorTypeFrequency = Metric.frequency("error_types")
const program = Effect.fail(new ConnectionFailedError()).pipe( Effect.trackErrors(errorTypeFrequency, (error: ConnectionFailedError) => error._tag))
Effect.runPromiseExit(program).then( () => Effect.runPromise(Metric.value(errorTypeFrequency)).then(console.log) // Output: { occurrences: Map(1) { "ConnectionFailedError" => 1 } })Signature
declare const trackErrors: { <Input, State, E>( metric: Metric.Metric<Input, State>, f: (error: E) => Input ): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R> <State, E>(metric: Metric.Metric<NoInfer<E>, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R, Input, State>( self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (error: E) => Input ): Effect<A, E, R> <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<NoInfer<E>, State>): Effect<A, E, R>}Since v4.0.0
trackSuccesses
Section titled “trackSuccesses”Updates the provided Metric every time the wrapped Effect succeeds with
a value.
Details
Also accepts an optional function which can be used to map the success value
of the Effect into a valid Input for the Metric.
Example (Counting successful results)
import { Effect, Metric } from "effect"
const successCounter = Metric.counter("successes").pipe(Metric.withConstantInput(1))
const program = Effect.succeed(42).pipe(Effect.trackSuccesses(successCounter))
Effect.runPromise(program).then( () => Effect.runPromise(Metric.value(successCounter)).then(console.log) // Output: { count: 1, incremental: false })Example (Mapping successes before tracking)
import { Effect, Metric } from "effect"
// Track successful request sizesconst requestSizeGauge = Metric.gauge("request_size_bytes")
const program = Effect.succeed("Hello World!").pipe( Effect.trackSuccesses(requestSizeGauge, (value: string) => value.length))
Effect.runPromise(program).then( () => Effect.runPromise(Metric.value(requestSizeGauge)).then(console.log) // Output: { value: 12 })Signature
declare const trackSuccesses: { <Input, State, A>( metric: Metric.Metric<Input, State>, f: (value: A) => Input ): <E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <State, A>(metric: Metric.Metric<NoInfer<A>, State>): <E, R>(self: Effect<A, E, R>) => Effect<A, E, R> <A, E, R, Input, State>( self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (value: A) => Input ): Effect<A, E, R> <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<NoInfer<A>, State>): Effect<A, E, R>}Since v4.0.0
transactions
Section titled “transactions”Transaction (class)
Section titled “Transaction (class)”Service that holds the current transaction state.
Details
It includes a journal that stores non-committed changes to TxRef values and
a retry flag that records whether the transaction should be retried.
Example (Building transactions)
import { Effect } from "effect"
// Transaction class for software transactional memory operationsconst txEffect = Effect.gen(function* () { const tx = yield* Effect.Transaction // Use transaction for coordinated state changes return "Transaction complete"})Signature
declare class TransactionSince v4.0.0
Defines a transaction boundary. Transactions are “all or nothing” with respect to changes made to transactional values (i.e. TxRef) that occur within the transaction body.
Details
If called inside an active transaction, tx composes with the current transaction and reuses
its journal and retry state instead of creating a nested boundary.
Effect transactions are optimistic with retry. A transaction is retried when
its body explicitly calls Effect.txRetry and any accessed transactional
value changes, or when any accessed transactional value changes because a
different transaction commits before the current one.
The outermost tx call creates the transaction boundary and commits or rolls back the full
composed transaction.
Example (Running a transaction)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function* () { const ref1 = yield* TxRef.make(0) const ref2 = yield* TxRef.make(0)
// Nested tx calls compose into the same transaction yield* Effect.tx( Effect.gen(function* () { yield* TxRef.set(ref1, 10) yield* Effect.tx(TxRef.set(ref2, 20)) const sum = (yield* TxRef.get(ref1)) + (yield* TxRef.get(ref2)) console.log(`Transaction sum: ${sum}`) }) )
console.log(`Final ref1: ${yield* TxRef.get(ref1)}`) // 10 console.log(`Final ref2: ${yield* TxRef.get(ref2)}`) // 20})Signature
declare const tx: <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, Exclude<R, Transaction>>Since v4.0.0
txRetry
Section titled “txRetry”Retries the current transaction by signaling that it must be retried.
Details
NOTE: the transaction retries on any change to transactional values (i.e. TxRef) accessed in its body.
Example (Retrying transactions)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function* () { // create a transactional reference const ref = yield* TxRef.make(0)
// forks a fiber that increases the value of `ref` every 100 millis yield* Effect.forkChild( Effect.forever( // update to transactional value Effect.tx(TxRef.update(ref, (n) => n + 1)).pipe(Effect.delay("100 millis")) ) )
// the following will retry 10 times until the `ref` value is 10 yield* Effect.tx( Effect.gen(function* () { const value = yield* TxRef.get(ref) if (value < 10) { yield* Effect.log(`retry due to value: ${value}`) return yield* Effect.txRetry } yield* Effect.log(`transaction done with value: ${value}`) }) )})
Effect.runPromise(program).catch(console.error)Signature
declare const txRetry: Effect<never, never, Transaction>Since v4.0.0
type IDs
Section titled “type IDs”TypeId
Section titled “TypeId”Runtime identifier used to recognize Effect values.
Signature
declare const TypeId: "~effect/Effect"Since v4.0.0
TypeId (type alias)
Section titled “TypeId (type alias)”Type-level identifier for Effect values.
Signature
type TypeId = "~effect/Effect"Since v4.0.0
type lambdas
Section titled “type lambdas”EffectTypeLambda (interface)
Section titled “EffectTypeLambda (interface)”Type lambda used to represent Effect in higher-kinded APIs.
Signature
export interface EffectTypeLambda extends TypeLambda { readonly type: Effect<this["Target"], this["Out1"], this["Out2"]>}Since v2.0.0
utility types
Section titled “utility types”satisfiesErrorType
Section titled “satisfiesErrorType”Ensures that an effect’s error type extends a given type E.
Details
This helper is checked at compile time and does not change the effect’s runtime behavior.
Example (Constraining the error type)
import { Data, Effect } from "effect"
class ValidationError extends Data.TaggedError("ValidationError")<{}> {}
// Define a constraint that the error type must be a ValidationErrorconst satisfiesError = Effect.satisfiesErrorType<ValidationError>()
// This works - Effect<number, ValidationError, never> extends the constrained typeconst validEffect = satisfiesError(Effect.fail(new ValidationError()))
// This would cause a TypeScript compilation error:// const invalidEffect = satisfiesError(Effect.fail("string error"))// ^^^^^^^^^^^^^^^^^^^^^^^^^^^// Type 'string' is not assignable to type 'ValidationError'Signature
declare const satisfiesErrorType: <E>() => <A, E2 extends E, R>(effect: Effect<A, E2, R>) => Effect<A, E2, R>Since v4.0.0
satisfiesServicesType
Section titled “satisfiesServicesType”Ensures that an effect’s requirements type extends a given type R.
Details
This helper is checked at compile time and does not change the effect’s runtime behavior.
Example (Constraining the services type)
import { Effect } from "effect"
// Define a constraint that requires a string as the requirements typeconst satisfiesStringServices = Effect.satisfiesServicesType<string>()
// This works - effect requires stringconst validEffect: Effect.Effect<number, never, "config"> = Effect.succeed(42)const constrainedEffect = satisfiesStringServices(validEffect)
// This would cause a TypeScript compilation error if uncommented:// const invalidEffect: Effect.Effect<number, never, number> = Effect.succeed(42)// const constrainedInvalid = satisfiesStringServices(invalidEffect)Signature
declare const satisfiesServicesType: <R>() => <A, E, R2 extends R>(effect: Effect<A, E, R2>) => Effect<A, E, R2>Since v4.0.0
satisfiesSuccessType
Section titled “satisfiesSuccessType”Ensures that an effect’s success type extends a given type A.
Details
This helper is checked at compile time and does not change the effect’s runtime behavior.
Example (Constraining the success type)
import { Effect } from "effect"
// Define a constraint that the success type must be a numberconst satisfiesNumber = Effect.satisfiesSuccessType<number>()
// This works - Effect<42, never, never> extends Effect<number, never, never>const validEffect = satisfiesNumber(Effect.succeed(42))
// This would cause a TypeScript compilation error:// const invalidEffect = satisfiesNumber(Effect.succeed("string"))// ^^^^^^^^^^^^^^^^^^^^^^// Type 'string' is not assignable to type 'number'Signature
declare const satisfiesSuccessType: <A>() => <A2 extends A, E, R>(effect: Effect<A2, E, R>) => Effect<A2, E, R>Since v4.0.0
All (namespace)
Section titled “All (namespace)”Namespace containing type utilities for the Effect.all function, which handles
collecting multiple effects into various output structures.
Since v2.0.0
EffectAny (type alias)
Section titled “EffectAny (type alias)”Alias for any Effect value accepted by Effect.all.
Signature
type EffectAny = Effect<any, any, any>Since v2.0.0
ReturnIterable (type alias)
Section titled “ReturnIterable (type alias)”Computes the return type for Effect.all when collecting an iterable.
Signature
type ReturnIterable<T, Discard, Mode> = [T] extends [Iterable<Effect<infer A, infer E, infer R>>] ? Effect< Discard extends true ? void : Array<Mode extends true ? Result.Result<A, E> : A>, Mode extends true ? never : E, R > : neverSince v2.0.0
ReturnTuple (type alias)
Section titled “ReturnTuple (type alias)”Computes the return type for Effect.all when collecting a tuple.
Signature
type Effect<Discard extends true ? void : T[number] extends never ? [] : { -readonly [K in keyof T]: T[K] extends Effect<infer _A, infer _E, infer _R> ? Mode extends true ? Result.Result<_A, _E> : _A : never; }, Mode extends true ? never : T[number] extends never ? never : T[number] extends Effect<infer _A, infer _E, infer _R> ? _E : never, T[number] extends never ? never : T[number] extends Effect<infer _A, infer _E, infer _R> ? _R : never> = Effect< Discard extends true ? void : T[number] extends never ? [] : { -readonly [K in keyof T]: T[K] extends Effect< infer _A, infer _E, infer _R > ? Mode extends true ? Result.Result<_A, _E> : _A : never }, Mode extends true ? never : T[number] extends never ? never : T[number] extends Effect<infer _A, infer _E, infer _R> ? _E : never, T[number] extends never ? never : T[number] extends Effect<infer _A, infer _E, infer _R> ? _R : never > extends infer X ? X : neverSince v2.0.0
ReturnObject (type alias)
Section titled “ReturnObject (type alias)”Computes the return type for Effect.all when collecting a record.
Signature
type ReturnObject<T, Discard, Mode> = [T] extends [Record<string, EffectAny>] ? Effect< Discard extends true ? void : { -readonly [K in keyof T]: [T[K]] extends [Effect<infer _A, infer _E, infer _R>] ? Mode extends true ? Result.Result<_A, _E> : _A : never }, Mode extends true ? never : keyof T extends never ? never : T[keyof T] extends Effect<infer _A, infer _E, infer _R> ? _E : never, keyof T extends never ? never : T[keyof T] extends Effect<infer _A, infer _E, infer _R> ? _R : never > : neverSince v2.0.0
IsDiscard (type alias)
Section titled “IsDiscard (type alias)”Detects whether Effect.all should discard collected values.
Signature
type IsDiscard<A> = [Extract<A, { readonly discard: true }>] extends [never] ? false : trueSince v2.0.0
IsResult (type alias)
Section titled “IsResult (type alias)”Detects whether Effect.all should collect results in Result mode.
Signature
type IsResult<A> = [Extract<A, { readonly mode: "result" }>] extends [never] ? false : trueSince v4.0.0
Return (type alias)
Section titled “Return (type alias)”Computes the return type for Effect.all from its input and options.
Signature
type Return<Arg, O> = [Arg] extends [ReadonlyArray<EffectAny>] ? ReturnTuple<Arg, IsDiscard<O>, IsResult<O>> : [Arg] extends [Iterable<EffectAny>] ? ReturnIterable<Arg, IsDiscard<O>, IsResult<O>> : [Arg] extends [Record<string, EffectAny>] ? ReturnObject<Arg, IsDiscard<O>, IsResult<O>> : neverSince v2.0.0
Effectify (namespace)
Section titled “Effectify (namespace)”Type helpers for converting callback-based functions into Effect functions.
Since v4.0.0
Effectify (type alias)
Section titled “Effectify (type alias)”Converts a callback-based function type into an Effect-returning function type.
Signature
type Effectify<T, E> = T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 (...args: ArgsWithCallback<infer Args5, infer _E5, infer A5>): infer _R5 (...args: ArgsWithCallback<infer Args6, infer _E6, infer A6>): infer _R6 (...args: ArgsWithCallback<infer Args7, infer _E7, infer A7>): infer _R7 (...args: ArgsWithCallback<infer Args8, infer _E8, infer A8>): infer _R8 (...args: ArgsWithCallback<infer Args9, infer _E9, infer A9>): infer _R9 (...args: ArgsWithCallback<infer Args10, infer _E10, infer A10>): infer _R10} ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> (...args: Args5): Effect<WithoutNull<A5>, E> (...args: Args6): Effect<WithoutNull<A6>, E> (...args: Args7): Effect<WithoutNull<A7>, E> (...args: Args8): Effect<WithoutNull<A8>, E> (...args: Args9): Effect<WithoutNull<A9>, E> (...args: Args10): Effect<WithoutNull<A10>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 (...args: ArgsWithCallback<infer Args5, infer _E5, infer A5>): infer _R5 (...args: ArgsWithCallback<infer Args6, infer _E6, infer A6>): infer _R6 (...args: ArgsWithCallback<infer Args7, infer _E7, infer A7>): infer _R7 (...args: ArgsWithCallback<infer Args8, infer _E8, infer A8>): infer _R8 (...args: ArgsWithCallback<infer Args9, infer _E9, infer A9>): infer _R9 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> (...args: Args5): Effect<WithoutNull<A5>, E> (...args: Args6): Effect<WithoutNull<A6>, E> (...args: Args7): Effect<WithoutNull<A7>, E> (...args: Args8): Effect<WithoutNull<A8>, E> (...args: Args9): Effect<WithoutNull<A9>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 (...args: ArgsWithCallback<infer Args5, infer _E5, infer A5>): infer _R5 (...args: ArgsWithCallback<infer Args6, infer _E6, infer A6>): infer _R6 (...args: ArgsWithCallback<infer Args7, infer _E7, infer A7>): infer _R7 (...args: ArgsWithCallback<infer Args8, infer _E8, infer A8>): infer _R8 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> (...args: Args5): Effect<WithoutNull<A5>, E> (...args: Args6): Effect<WithoutNull<A6>, E> (...args: Args7): Effect<WithoutNull<A7>, E> (...args: Args8): Effect<WithoutNull<A8>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 (...args: ArgsWithCallback<infer Args5, infer _E5, infer A5>): infer _R5 (...args: ArgsWithCallback<infer Args6, infer _E6, infer A6>): infer _R6 (...args: ArgsWithCallback<infer Args7, infer _E7, infer A7>): infer _R7 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> (...args: Args5): Effect<WithoutNull<A5>, E> (...args: Args6): Effect<WithoutNull<A6>, E> (...args: Args7): Effect<WithoutNull<A7>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 (...args: ArgsWithCallback<infer Args5, infer _E5, infer A5>): infer _R5 (...args: ArgsWithCallback<infer Args6, infer _E6, infer A6>): infer _R6 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> (...args: Args5): Effect<WithoutNull<A5>, E> (...args: Args6): Effect<WithoutNull<A6>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 (...args: ArgsWithCallback<infer Args5, infer _E5, infer A5>): infer _R5 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> (...args: Args5): Effect<WithoutNull<A5>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 (...args: ArgsWithCallback<infer Args4, infer _E4, infer A4>): infer _R4 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> (...args: Args4): Effect<WithoutNull<A4>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 (...args: ArgsWithCallback<infer Args3, infer _E3, infer A3>): infer _R3 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> (...args: Args3): Effect<WithoutNull<A3>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 (...args: ArgsWithCallback<infer Args2, infer _E2, infer A2>): infer _R2 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> (...args: Args2): Effect<WithoutNull<A2>, E> } : T extends { (...args: ArgsWithCallback<infer Args1, infer _E1, infer A1>): infer _R1 } ? { (...args: Args1): Effect<WithoutNull<A1>, E> } : neverSince v4.0.0
EffectifyError (type alias)
Section titled “EffectifyError (type alias)”Extracts the callback error type from a callback-based function type.
Signature
type EffectifyError<T> = T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 (...args: ArgsWithCallback<infer _Args5, infer E5, infer _A5>): infer _R5 (...args: ArgsWithCallback<infer _Args6, infer E6, infer _A6>): infer _R6 (...args: ArgsWithCallback<infer _Args7, infer E7, infer _A7>): infer _R7 (...args: ArgsWithCallback<infer _Args8, infer E8, infer _A8>): infer _R8 (...args: ArgsWithCallback<infer _Args9, infer E9, infer _A9>): infer _R9 (...args: ArgsWithCallback<infer _Args10, infer E10, infer _A10>): infer _R10} ? NonNullable<E1 | E2 | E3 | E4 | E5 | E6 | E7 | E8 | E9 | E10> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 (...args: ArgsWithCallback<infer _Args5, infer E5, infer _A5>): infer _R5 (...args: ArgsWithCallback<infer _Args6, infer E6, infer _A6>): infer _R6 (...args: ArgsWithCallback<infer _Args7, infer E7, infer _A7>): infer _R7 (...args: ArgsWithCallback<infer _Args8, infer E8, infer _A8>): infer _R8 (...args: ArgsWithCallback<infer _Args9, infer E9, infer _A9>): infer _R9 } ? NonNullable<E1 | E2 | E3 | E4 | E5 | E6 | E7 | E8 | E9> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 (...args: ArgsWithCallback<infer _Args5, infer E5, infer _A5>): infer _R5 (...args: ArgsWithCallback<infer _Args6, infer E6, infer _A6>): infer _R6 (...args: ArgsWithCallback<infer _Args7, infer E7, infer _A7>): infer _R7 (...args: ArgsWithCallback<infer _Args8, infer E8, infer _A8>): infer _R8 } ? NonNullable<E1 | E2 | E3 | E4 | E5 | E6 | E7 | E8> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 (...args: ArgsWithCallback<infer _Args5, infer E5, infer _A5>): infer _R5 (...args: ArgsWithCallback<infer _Args6, infer E6, infer _A6>): infer _R6 (...args: ArgsWithCallback<infer _Args7, infer E7, infer _A7>): infer _R7 } ? NonNullable<E1 | E2 | E3 | E4 | E5 | E6 | E7> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 (...args: ArgsWithCallback<infer _Args5, infer E5, infer _A5>): infer _R5 (...args: ArgsWithCallback<infer _Args6, infer E6, infer _A6>): infer _R6 } ? NonNullable<E1 | E2 | E3 | E4 | E5 | E6> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 (...args: ArgsWithCallback<infer _Args5, infer E5, infer _A5>): infer _R5 } ? NonNullable<E1 | E2 | E3 | E4 | E5> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 (...args: ArgsWithCallback<infer _Args4, infer E4, infer _A4>): infer _R4 } ? NonNullable<E1 | E2 | E3 | E4> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 (...args: ArgsWithCallback<infer _Args3, infer E3, infer _A3>): infer _R3 } ? NonNullable<E1 | E2 | E3> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 (...args: ArgsWithCallback<infer _Args2, infer E2, infer _A2>): infer _R2 } ? NonNullable<E1 | E2> : T extends { (...args: ArgsWithCallback<infer _Args1, infer E1, infer _A1>): infer _R1 } ? NonNullable<E1> : neverSince v4.0.0
Repeat (namespace)
Section titled “Repeat (namespace)”Type helpers for repeating effects.
Since v2.0.0
Options (interface)
Section titled “Options (interface)”Options that control whether and how an effect is repeated.
Signature
export interface Options<A> { while?: ((_: A) => boolean | Effect<boolean, any, any>) | undefined until?: ((_: A) => boolean | Effect<boolean, any, any>) | undefined times?: number | undefined schedule?: Schedule<any, A, any, any> | undefined}Since v2.0.0
Return (type alias)
Section titled “Return (type alias)”Computes the result type of Effect.repeat from the original effect and repeat options.
Signature
type Effect<O extends { until: Predicate.Refinement<A, infer B>; } ? B : O extends { while: Predicate.Refinement<A, infer B>; } ? Exclude<A, B> : A, E | (O extends { schedule: Schedule<infer _Out, infer _I, infer E, infer _R>; } ? E : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>; } ? E : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>; } ? E : never), R | (O extends { schedule: Schedule<infer _O, infer _I, infer _E, infer R>; } ? R : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>; } ? R : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>; } ? R : never)> = Effect< O extends { until: Predicate.Refinement<A, infer B> } ? B : O extends { while: Predicate.Refinement<A, infer B> } ? Exclude<A, B> : A, | E | (O extends { schedule: Schedule<infer _Out, infer _I, infer E, infer _R> } ? E : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer E, infer _R> } ? E : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer E, infer _R> } ? E : never), | R | (O extends { schedule: Schedule<infer _O, infer _I, infer _E, infer R> } ? R : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer _E, infer R> } ? R : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer _E, infer R> } ? R : never) > extends infer Z ? Z : neverSince v2.0.0
Retry (namespace)
Section titled “Retry (namespace)”Type helpers for retrying effects.
Since v2.0.0
Options (interface)
Section titled “Options (interface)”Options that control whether and how a failing effect is retried.
Signature
export interface Options<E> { while?: ((error: E) => boolean | Effect<boolean, any, any>) | undefined until?: ((error: E) => boolean | Effect<boolean, any, any>) | undefined times?: number | undefined schedule?: Schedule<any, E, any, any> | undefined}Since v2.0.0
Return (type alias)
Section titled “Return (type alias)”Computes the result type of Effect.retry from the original effect and retry options.
Signature
type Effect<A, (O extends { schedule: Schedule<infer _O, infer _I, infer _E1, infer _R>; } ? E : O extends { times: number; } ? E : O extends { until: Predicate.Refinement<E, infer E2>; } ? E2 : O extends { while: Predicate.Refinement<E, infer E2>; } ? Exclude<E, E2> : E) | (O extends { schedule: Schedule<infer _O, infer _I, infer E, infer _R>; } ? E : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>; } ? E : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>; } ? E : never), R | (O extends { schedule: Schedule<infer _O, infer _I, infer _E1, infer R>; } ? R : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>; } ? R : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>; } ? R : never)> = Effect< A, | (O extends { schedule: Schedule<infer _O, infer _I, infer _E1, infer _R> } ? E : O extends { times: number } ? E : O extends { until: Predicate.Refinement<E, infer E2> } ? E2 : O extends { while: Predicate.Refinement<E, infer E2> } ? Exclude<E, E2> : E) | (O extends { schedule: Schedule<infer _O, infer _I, infer E, infer _R> } ? E : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer E, infer _R> } ? E : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer E, infer _R> } ? E : never), | R | (O extends { schedule: Schedule<infer _O, infer _I, infer _E1, infer R> } ? R : never) | (O extends { while: (...args: Array<any>) => Effect<infer _A, infer _E, infer R> } ? R : never) | (O extends { until: (...args: Array<any>) => Effect<infer _A, infer _E, infer R> } ? R : never) > extends infer Z ? Z : neverSince v2.0.0
fn (namespace)
Section titled “fn (namespace)”Type helpers for functions built with Effect.fn and Effect.fnUntraced.
Details
Use these to describe generator-based signatures and traced or untraced variants.
Since v3.11.0
Return (type alias)
Section titled “Return (type alias)”Generator return type accepted by fn and fnUntraced.
When to use
Use when you need to annotate the return type of a generator body while
keeping the produced function’s Effect return type inferred.
Example (Annotating an Effect function)
import { Effect } from "effect"
const f = Effect.fnUntraced(function* (value: string): Effect.fn.Return<number> { return yield* Effect.succeed(value.length)})
// ┌─── Effect.Effect<number>// ▼const program = f("hello")Example (Annotating a parametric Effect function)
import { Effect } from "effect"
const f = Effect.fnUntraced(function* <A>(value: A): Effect.fn.Return<A> { return yield* Effect.succeed(value)})
// ┌─── Effect.Effect<string>// ▼const program = f("hello")Signature
type Return<A, E, R> = Generator<Effect<any, E, R>, A, any>Since v3.19.0
Untraced (type alias)
Section titled “Untraced (type alias)”Type of the untraced function builder used by Effect.fnUntraced.
Signature
type Untraced = { <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> ): ( ...args: Args ) => Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never > <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> ): ( this: Self, ...args: Args ) => Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A ): (...args: Args) => A <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A ): (this: Self, ...args: Args) => A <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B ): (...args: Args) => B <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B ): (this: Self, ...args: Args) => B <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C ): (...args: Args) => C <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C ): (this: Self, ...args: Args) => C <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D>( body: (...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D ): (...args: Args) => D <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D ): (this: Self, ...args: Args) => D <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E ): (...args: Args) => E <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E ): (this: Self, ...args: Args) => E <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F ): (...args: Args) => F <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F ): (this: Self, ...args: Args) => F <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G ): (...args: Args) => G <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G ): (this: Self, ...args: Args) => G <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H ): (...args: Args) => H <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H ): (this: Self, ...args: Args) => H <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I ): (...args: Args) => I <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I ): (this: Self, ...args: Args) => I <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J ): (...args: Args) => J <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J ): (this: Self, ...args: Args) => J <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K ): (...args: Args) => K <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K ): (this: Self, ...args: Args) => K <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L ): (...args: Args) => L <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L ): (this: Self, ...args: Args) => L <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M ): (...args: Args) => M <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M ): (this: Self, ...args: Args) => M <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N ): (...args: Args) => N <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N ): (this: Self, ...args: Args) => N <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O ): (...args: Args) => O <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O ): (this: Self, ...args: Args) => O <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P ): (...args: Args) => P < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P ): (this: Self, ...args: Args) => P <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q ): (...args: Args) => Q < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q ): (this: Self, ...args: Args) => Q < Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R >( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R ): (...args: Args) => R < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R ): (this: Self, ...args: Args) => R < Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S >( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S ): (...args: Args) => S < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S ): (this: Self, ...args: Args) => S < Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T >( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S, t: (_: S, ...args: Args) => T ): (...args: Args) => T < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never>, a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S, t: (_: S, ...args: Args) => T ): (this: Self, ...args: Args) => T}Since v3.11.0
Traced (type alias)
Section titled “Traced (type alias)”Type of the traced function builder used by Effect.fn.
Signature
type Traced = { <Eff extends Effect<any, any, any>, AEff, Args extends Array<any>>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>) ): ( ...args: Args ) => Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never > <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>) ): ( this: Self, ...args: Args ) => Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never > <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>) ): ( ...args: Args ) => Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A ): (...args: Args) => A <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A ): (this: Self, ...args: Args) => A <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A ): (...args: Args) => A
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B ): (...args: Args) => B <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B ): (this: Self, ...args: Args) => B <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B ): (...args: Args) => B
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C ): (...args: Args) => C <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C ): (this: Self, ...args: Args) => C <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C ): (...args: Args) => C
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D ): (...args: Args) => D <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D ): (this: Self, ...args: Args) => D
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D ): (...args: Args) => D
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E ): (...args: Args) => E <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E ): (this: Self, ...args: Args) => E
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E ): (...args: Args) => E
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F ): (...args: Args) => F <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F ): (this: Self, ...args: Args) => F
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F ): (...args: Args) => F
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G ): (...args: Args) => G <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G ): (this: Self, ...args: Args) => G
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G ): (...args: Args) => G
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H ): (...args: Args) => H <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H ): (this: Self, ...args: Args) => H
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H ): (...args: Args) => H
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I ): (...args: Args) => I <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I ): (this: Self, ...args: Args) => I
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I ): (...args: Args) => I
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J ): (...args: Args) => J <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J ): (this: Self, ...args: Args) => J
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J ): (...args: Args) => J
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K ): (...args: Args) => K <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K ): (this: Self, ...args: Args) => K
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K ): (...args: Args) => K
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L ): (...args: Args) => L <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L ): (this: Self, ...args: Args) => L
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L ): (...args: Args) => L
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M ): (...args: Args) => M <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M ): (this: Self, ...args: Args) => M
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M ): (...args: Args) => M
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N ): (...args: Args) => N <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N ): (this: Self, ...args: Args) => N
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N ): (...args: Args) => N
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O ): (...args: Args) => O <Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O ): (this: Self, ...args: Args) => O
<Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O ): (...args: Args) => O
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P ): (...args: Args) => P < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P ): (this: Self, ...args: Args) => P
< Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P >( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P ): (...args: Args) => P
<Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q ): (...args: Args) => Q < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q ): (this: Self, ...args: Args) => Q
< Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q >( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q ): (...args: Args) => Q
< Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R >( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R ): (...args: Args) => R < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R ): (this: Self, ...args: Args) => R
< Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R >( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R ): (...args: Args) => R
< Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S >( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S ): (...args: Args) => S < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S ): (this: Self, ...args: Args) => S
< Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S >( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S ): (...args: Args) => S
< Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T >( body: (this: unassigned, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S, t: (_: S, ...args: Args) => T ): (...args: Args) => T < Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T >( body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S, t: (_: S, ...args: Args) => T ): (this: Self, ...args: Args) => T
< Self, Eff extends Effect<any, any, any>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T >( options: { readonly self: Self }, body: (this: Self, ...args: Args) => Generator<Eff, AEff, never> | (Eff & Effect<AEff, any, any>), a: ( _: Effect< AEff, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect<infer _A, infer _E, infer R>] ? R : never >, ...args: Args ) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J, k: (_: J, ...args: Args) => K, l: (_: K, ...args: Args) => L, m: (_: L, ...args: Args) => M, n: (_: M, ...args: Args) => N, o: (_: N, ...args: Args) => O, p: (_: O, ...args: Args) => P, q: (_: P, ...args: Args) => Q, r: (_: Q, ...args: Args) => R, s: (_: R, ...args: Args) => S, t: (_: S, ...args: Args) => T ): (...args: Args) => T}Since v4.0.0
gen (namespace)
Section titled “gen (namespace)”Type helpers for Effect.gen generator return signatures.
Since v2.0.0
Return (type alias)
Section titled “Return (type alias)”Generator return type accepted by Effect.gen.
Signature
type Return<A, E, R> = Generator<Effect<any, E, R>, A, any>Since v4.0.0
zipping
Section titled “zipping”Combines two effects into a single effect, producing a tuple with the results of both effects.
When to use
Use to combine exactly two effects into a tuple.
Details
The zip function executes the first effect (left) and then the second effect (right).
Once both effects succeed, their results are combined into a tuple.
Concurrency:
By default, zip processes the effects sequentially. To execute the effects concurrently,
use the { concurrent: true } option.
Example (Combining two effects sequentially)
import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")))const task2 = Effect.succeed("hello").pipe(Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done")))
// Combine the two effects together//// ┌─── Effect<[number, string], never, never>// ▼const program = Effect.zip(task1, task2)
Effect.runPromise(program).then(console.log)// Output:// timestamp=... level=INFO fiber=#0 message="task1 done"// timestamp=... level=INFO fiber=#0 message="task2 done"// [ 1, 'hello' ]Example (Combining two effects concurrently)
import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")))const task2 = Effect.succeed("hello").pipe(Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done")))
// Run both effects concurrently using the concurrent optionconst program = Effect.zip(task1, task2, { concurrent: true })
Effect.runPromise(program).then(console.log)// Output:// timestamp=... level=INFO fiber=#0 message="task2 done"// timestamp=... level=INFO fiber=#0 message="task1 done"// [ 1, 'hello' ]See
zipWithfor a version that combines the results with a custom function.allfor collecting a larger structure of effects.
Signature
declare const zip: { <A2, E2, R2>( that: Effect<A2, E2, R2>, options?: { readonly concurrent?: boolean | undefined } | undefined ): <A, E, R>(self: Effect<A, E, R>) => Effect<[A, A2], E2 | E, R2 | R> <A, E, R, A2, E2, R2>( self: Effect<A, E, R>, that: Effect<A2, E2, R2>, options?: { readonly concurrent?: boolean | undefined } ): Effect<[A, A2], E | E2, R | R2>}Since v2.0.0
zipWith
Section titled “zipWith”Combines two effects sequentially and applies a function to their results to produce a single value.
When to use
Use when you need to run two effects sequentially and combine their results with a function instead of keeping the results as a tuple.
Details
Concurrency:
By default, the effects are run sequentially. To execute them concurrently,
use the { concurrent: true } option.
Example (Combining two success values with a function)
import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")))const task2 = Effect.succeed("hello").pipe(Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done")))
const task3 = Effect.zipWith( task1, task2, // Combines results into a single value (number, string) => number + string.length)
Effect.runPromise(task3).then(console.log)// Output:// timestamp=... level=INFO fiber=#3 message="task1 done"// timestamp=... level=INFO fiber=#2 message="task2 done"// 6Signature
declare const zipWith: { <A2, E2, R2, A, B>( that: Effect<A2, E2, R2>, f: (a: A, b: A2) => B, options?: { readonly concurrent?: boolean | undefined } ): <E, R>(self: Effect<A, E, R>) => Effect<B, E2 | E, R2 | R> <A, E, R, A2, E2, R2, B>( self: Effect<A, E, R>, that: Effect<A2, E2, R2>, f: (a: A, b: A2) => B, options?: { readonly concurrent?: boolean | undefined } ): Effect<B, E2 | E, R2 | R>}Since v2.0.0