<B, A, A2, E2, R2, C, E3, R3>(
sink: Sink.Sink<B, A | A2, A2, E2, R2>,
schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>
): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>
<A, E, R, B, A2, E2, R2, C, E3, R3>(
self: Stream<A, E, R>,
sink: Sink.Sink<B, A | A2, A2, E2, R2>,
schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>
): Stream<B, E | E2 | E3, R | R2 | R3>Aggregates elements with a sink, emitting each result when the sink completes or the schedule triggers.
Details
The schedule can flush the current aggregation even if the sink has not finished.
Example (Aggregating with a sink and schedule)
import { Console, Effect, Schedule, Sink, Stream } from "effect"
Effect.runPromise(Effect.gen(function* () {
const aggregated = yield* Stream.runCollect(
Stream.make(1, 2, 3, 4, 5, 6).pipe(
Stream.aggregateWithin(
Sink.foldUntil(() => 0, 3, (sum, n) => Effect.succeed(sum + n)),
Schedule.spaced("1 minute")
)
)
)
yield* Console.log(aggregated)
}))
// Output: [ 6, 15 ]export const const aggregateWithin: {
<B, A, A2, E2, R2, C, E3, R3>(
sink: Sink.Sink<B, A | A2, A2, E2, R2>,
schedule: Schedule.Schedule<
C,
Option.Option<B>,
E3,
R3
>
): <E, R>(
self: Stream<A, E, R>
) => Stream<B, E2 | E | E3, R2 | R3 | R>
<A, E, R, B, A2, E2, R2, C, E3, R3>(
self: Stream<A, E, R>,
sink: Sink.Sink<B, A | A2, A2, E2, R2>,
schedule: Schedule.Schedule<
C,
Option.Option<B>,
E3,
R3
>
): Stream<B, E | E2 | E3, R | R2 | R3>
}
Aggregates elements with a sink, emitting each result when the sink completes or the schedule triggers.
Details
The schedule can flush the current aggregation even if the sink has not finished.
Example (Aggregating with a sink and schedule)
import { Console, Effect, Schedule, Sink, Stream } from "effect"
Effect.runPromise(Effect.gen(function* () {
const aggregated = yield* Stream.runCollect(
Stream.make(1, 2, 3, 4, 5, 6).pipe(
Stream.aggregateWithin(
Sink.foldUntil(() => 0, 3, (sum, n) => Effect.succeed(sum + n)),
Schedule.spaced("1 minute")
)
)
)
yield* Console.log(aggregated)
}))
// Output: [ 6, 15 ]
aggregateWithin: {
<function (type parameter) B in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>B, function (type parameter) A in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>A, function (type parameter) A2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>A2, function (type parameter) E2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>E2, function (type parameter) R2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>R2, function (type parameter) C in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>C, function (type parameter) E3 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>E3, function (type parameter) R3 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>R3>(
sink: Sink.Sink<B, A | A2, A2, E2, R2>(parameter) sink: {
transform: (upstream: Pull.Pull<NonEmptyReadonlyArray<In>, never, void>, scope: Scope.Scope) => Effect.Effect<End<A, L>, E, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
sink: import SinkSink.interface Sink<out A, in In = unknown, out L = never, out E = never, out R = never>A Sink<A, In, L, E, R> is used to consume elements produced by a Stream.
You can think of a sink as a function that will consume a variable amount of
In elements (could be 0, 1, or many), might fail with an error of type E,
and will eventually yield a value of type A together with a remainder of
type L (i.e. any leftovers).
Example (Running a sink with a stream)
import { Effect, Sink, Stream } from "effect"
// Create a simple sink that always succeeds with a value
const sink: Sink.Sink<number> = Sink.succeed(42)
// Use the sink to consume a stream
const stream = Stream.make(1, 2, 3)
const program = Stream.run(stream, sink)
Effect.runPromise(program).then(console.log)
// Output: 42
Namespace containing types and interfaces for Sink variance and type relationships.
Sink<function (type parameter) B in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>B, function (type parameter) A in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>A | function (type parameter) A2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>A2, function (type parameter) A2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>A2, function (type parameter) E2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>E2, function (type parameter) R2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>R2>,
schedule: Schedule.Schedule<
C,
Option.Option<B>,
E3,
R3
>
(parameter) schedule: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
schedule: import ScheduleSchedule.interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) C in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>C, import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<function (type parameter) B in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>B>, function (type parameter) E3 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>E3, function (type parameter) R3 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>R3>
): <function (type parameter) E in <E, R>(self: Stream<A, E, R>): Stream<B, E2 | E | E3, R2 | R3 | R>E, function (type parameter) R in <E, R>(self: Stream<A, E, R>): Stream<B, E2 | E | E3, R2 | R3 | R>R>(self: Stream<A, E, R>(parameter) self: {
channel: Channel.Channel<Arr.NonEmptyReadonlyArray<A>, E, void, unknown, unknown, unknown, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self: interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) A in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>A, function (type parameter) E in <E, R>(self: Stream<A, E, R>): Stream<B, E2 | E | E3, R2 | R3 | R>E, function (type parameter) R in <E, R>(self: Stream<A, E, R>): Stream<B, E2 | E | E3, R2 | R3 | R>R>) => interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) B in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>B, function (type parameter) E2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>E2 | function (type parameter) E in <E, R>(self: Stream<A, E, R>): Stream<B, E2 | E | E3, R2 | R3 | R>E | function (type parameter) E3 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>E3, function (type parameter) R2 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>R2 | function (type parameter) R3 in <B, A, A2, E2, R2, C, E3, R3>(sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): <E, R>(self: Stream<A, E, R>) => Stream<B, E2 | E | E3, R2 | R3 | R>R3 | function (type parameter) R in <E, R>(self: Stream<A, E, R>): Stream<B, E2 | E | E3, R2 | R3 | R>R>
<function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E, function (type parameter) R in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R, function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2, function (type parameter) E2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E2, function (type parameter) R2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R2, function (type parameter) C in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>C, function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3>(
self: Stream<A, E, R>(parameter) self: {
channel: Channel.Channel<Arr.NonEmptyReadonlyArray<A>, E, void, unknown, unknown, unknown, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self: interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E, function (type parameter) R in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R>,
sink: Sink.Sink<B, A | A2, A2, E2, R2>(parameter) sink: {
transform: (upstream: Pull.Pull<NonEmptyReadonlyArray<In>, never, void>, scope: Scope.Scope) => Effect.Effect<End<A, L>, E, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
sink: import SinkSink.interface Sink<out A, in In = unknown, out L = never, out E = never, out R = never>A Sink<A, In, L, E, R> is used to consume elements produced by a Stream.
You can think of a sink as a function that will consume a variable amount of
In elements (could be 0, 1, or many), might fail with an error of type E,
and will eventually yield a value of type A together with a remainder of
type L (i.e. any leftovers).
Example (Running a sink with a stream)
import { Effect, Sink, Stream } from "effect"
// Create a simple sink that always succeeds with a value
const sink: Sink.Sink<number> = Sink.succeed(42)
// Use the sink to consume a stream
const stream = Stream.make(1, 2, 3)
const program = Stream.run(stream, sink)
Effect.runPromise(program).then(console.log)
// Output: 42
Namespace containing types and interfaces for Sink variance and type relationships.
Sink<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A | function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2, function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2, function (type parameter) E2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E2, function (type parameter) R2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R2>,
schedule: Schedule.Schedule<
C,
Option.Option<B>,
E3,
R3
>
(parameter) schedule: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
schedule: import ScheduleSchedule.interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) C in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>C, import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B>, function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3>
): interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E | function (type parameter) E2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E2 | function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, function (type parameter) R in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R | function (type parameter) R2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R2 | function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3>
} = dual<(...args: Array<any>) => any, <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>) => Stream<B, E | E2 | E3, R | R2 | R3>>(arity: 3, body: <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>) => Stream<B, E | E2 | E3, R | R2 | R3>): ((...args: Array<any>) => any) & (<A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>) => Stream<B, E | E2 | E3, R | R2 | R3>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(3, <function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E, function (type parameter) R in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R, function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2, function (type parameter) E2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E2, function (type parameter) R2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R2, function (type parameter) C in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>C, function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3>(
self: Stream<A, E, R>(parameter) self: {
channel: Channel.Channel<Arr.NonEmptyReadonlyArray<A>, E, void, unknown, unknown, unknown, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self: interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E, function (type parameter) R in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R>,
sink: Sink.Sink<B, A | A2, A2, E2, R2>(parameter) sink: {
transform: (upstream: Pull.Pull<NonEmptyReadonlyArray<In>, never, void>, scope: Scope.Scope) => Effect.Effect<End<A, L>, E, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
sink: import SinkSink.interface Sink<out A, in In = unknown, out L = never, out E = never, out R = never>A Sink<A, In, L, E, R> is used to consume elements produced by a Stream.
You can think of a sink as a function that will consume a variable amount of
In elements (could be 0, 1, or many), might fail with an error of type E,
and will eventually yield a value of type A together with a remainder of
type L (i.e. any leftovers).
Example (Running a sink with a stream)
import { Effect, Sink, Stream } from "effect"
// Create a simple sink that always succeeds with a value
const sink: Sink.Sink<number> = Sink.succeed(42)
// Use the sink to consume a stream
const stream = Stream.make(1, 2, 3)
const program = Stream.run(stream, sink)
Effect.runPromise(program).then(console.log)
// Output: 42
Namespace containing types and interfaces for Sink variance and type relationships.
Sink<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A | function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2, function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2, function (type parameter) E2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E2, function (type parameter) R2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R2>,
schedule: Schedule.Schedule<
C,
Option.Option<B>,
E3,
R3
>
(parameter) schedule: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
schedule: import ScheduleSchedule.interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) C in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>C, import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B>, function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3>
): interface Stream<out A, out E = never, out R = never>A Stream<A, E, R> describes a program that can emit many A values, fail
with E, and require R.
Details
Streams are pull-based with backpressure and emit chunks to amortize effect
evaluation. They support monadic composition and error handling similar to
Effect, adapted for multiple values.
Example (Creating and consuming streams)
import { Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
yield* Stream.make(1, 2, 3).pipe(
Stream.map((n) => n * 2),
Stream.runForEach((n) => Console.log(n))
)
})
Effect.runPromise(program)
// Output:
// 2
// 4
// 6
Stream<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E | function (type parameter) E2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E2 | function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, function (type parameter) R in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R | function (type parameter) R2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R2 | function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3> =>
const fromChannel: <
Arr extends Arr.NonEmptyReadonlyArray<any>,
E,
R
>(
channel: Channel.Channel<
Arr,
E,
void,
unknown,
unknown,
unknown,
R
>
) => Stream<
Arr extends Arr.NonEmptyReadonlyArray<infer A>
? A
: never,
E,
R
>
Creates a stream from a array-emitting Channel.
Example (Creating a stream from an array-emitting channel)
import { Channel, Console, Effect, Stream } from "effect"
const program = Effect.gen(function*() {
const channel = Channel.succeed([1, 2, 3] as const)
const stream = Stream.fromChannel(channel)
const result = yield* Stream.runCollect(stream)
yield* Console.log(result)
})
// Output: [ 1, 2, 3 ]
fromChannel(import ChannelChannel.const fromTransformBracket: <
OutElem,
OutErr,
OutDone,
InElem,
InErr,
InDone,
EX,
EnvX,
Env
>(
f: (
upstream: Pull.Pull<InElem, InErr, InDone>,
scope: Scope.Scope,
forkedScope: Scope.Scope
) => Effect.Effect<
Pull.Pull<OutElem, OutErr, OutDone, EnvX>,
EX,
Env
>
) => Channel<
OutElem,
Pull.ExcludeDone<OutErr> | EX,
OutDone,
InElem,
InErr,
InDone,
Env | EnvX
>
Creates a Channel from a transformation function that operates on upstream
pulls, but also provides a forked scope that closes when the resulting
Channel completes.
When to use
Use when building channels that require scoped resource lifecycle management,
providing both the channel scope and a forked scope that automatically closes
when the channel completes.
fromTransformBracket(import EffectEffect.const fnUntraced: <Effect.Effect<Queue.Queue<readonly [A, ...A[]] | unique symbol, Cause.Done<void> | E>, never, never> | Effect.Effect<Pull.Pull<readonly [A, ...A[]], E, void, R>, never, R> | Effect.Effect<Fiber.Fiber<boolean, never>, never, R> | Effect.Effect<(input: Option.Option<B>) => Pull.Pull<C, E3, C, R3>, never, R3>, Effect.Effect<[B, ...B[]], Cause.Done<void> | E | E2 | E3, R2 | R3>, [_upstream: ...]>(body: (this: unassigned, _upstream: Pull.Pull<...>, _: Scope.Scope, scope: Scope.Scope) => Generator<...>) => (_upstream: Pull.Pull<...>, _: Scope.Scope, scope: Scope.Scope) => Effect.Effect<...> (+41 overloads)fnUntraced(function*(_upstream: Pull.Pull<
unknown,
unknown,
unknown,
never
>
(parameter) _upstream: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
_upstream, _: Scope.Scope(parameter) _: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
_, scope: Scope.Scope(parameter) scope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
scope) {
const const pull: Pull.Pull<
readonly [A, ...A[]],
E,
void,
R
>
const pull: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
pull = yield* import ChannelChannel.const toPullScoped: <
OutElem,
OutErr,
OutDone,
Env
>(
self: Channel<
OutElem,
OutErr,
OutDone,
unknown,
unknown,
unknown,
Env
>,
scope: Scope.Scope
) => Effect.Effect<
Pull.Pull<OutElem, OutErr, OutDone, Env>,
never,
Env
>
Converts a channel to a Pull within an existing scope.
Example (Converting channels to scoped pulls)
import { Channel, Data, Effect, Scope } from "effect"
class ScopedPullError extends Data.TaggedError("ScopedPullError")<{
readonly reason: string
}> {}
// Create a channel
const numbersChannel = Channel.fromIterable([1, 2, 3])
// Convert to Pull with explicit scope
const scopedPullEffect = Effect.gen(function*() {
const scope = yield* Scope.make()
const pull = yield* Channel.toPullScoped(numbersChannel, scope)
return pull
})
toPullScoped(self: Stream<A, E, R>(parameter) self: {
channel: Channel.Channel<Arr.NonEmptyReadonlyArray<A>, E, void, unknown, unknown, unknown, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.Stream<A, E, R>.channel: Channel.Channel<Arr.NonEmptyReadonlyArray<A>, E, void, unknown, unknown, unknown, R>(property) Stream<A, E, R>.channel: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
channel, _: Scope.Scope(parameter) _: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
_)
const const pullLatch: Latch.Latchconst pullLatch: {
open: Effect.Effect<boolean>;
openUnsafe: (this: Latch) => boolean;
release: Effect.Effect<boolean>;
await: Effect.Effect<void>;
close: Effect.Effect<boolean>;
closeUnsafe: (this: Latch) => boolean;
whenOpen: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
isOpen: (this: Latch) => boolean;
}
pullLatch = import LatchLatch.const makeUnsafe: (
open?: boolean | undefined
) => Latch
Creates a Latch synchronously, outside of Effect.
When to use
Use when you need to allocate a Latch synchronously outside an Effect
workflow.
Details
The latch starts closed by default; pass true to create it open.
Example (Creating a latch unsafely)
import { Effect, Latch } from "effect"
const latch = Latch.makeUnsafe(false)
const waiter = Effect.gen(function*() {
yield* Effect.log("Waiting for latch to open...")
yield* latch.await
yield* Effect.log("Latch opened! Continuing...")
})
const opener = Effect.gen(function*() {
yield* Effect.sleep("2 seconds")
yield* Effect.log("Opening latch...")
yield* latch.open
})
const program = Effect.all([waiter, opener])
makeUnsafe(false)
const const scheduleStep: unique symbolscheduleStep = var Symbol: SymbolConstructor
;(description?: string | number) => symbol
Returns a new unique Symbol value.
Symbol()
const const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer = yield* import QueueQueue.const make: <A, E = never>(
options?:
| {
readonly capacity?: number | undefined
readonly strategy?:
| "suspend"
| "dropping"
| "sliding"
| undefined
}
| undefined
) => Effect<Queue<A, E>>
Creates a Queue with optional capacity and overflow strategy.
Details
By default the queue is unbounded and uses the "suspend" strategy. Provide
capacity for a bounded queue and choose "suspend", "dropping", or
"sliding" to control what happens when the queue is full. The returned
queue can be offered to, taken from, failed, ended, interrupted, or shut down.
Example (Creating queues)
import { Cause, Effect, Queue } from "effect"
Effect.gen(function*() {
const queue = yield* Queue.make<number, string | Cause.Done>()
// add messages to the queue
yield* Queue.offer(queue, 1)
yield* Queue.offer(queue, 2)
yield* Queue.offerAll(queue, [3, 4, 5])
// take messages from the queue
const messages = yield* Queue.takeAll(queue)
console.log(messages) // [1, 2, 3, 4, 5]
// signal that the queue is done
yield* Queue.end(queue)
const done = yield* Effect.flip(Queue.take(queue))
console.log(Cause.isDone(done)) // true
// signal that another queue has failed
const failedQueue = yield* Queue.make<number, string>()
const failed = yield* Queue.fail(failedQueue, "boom")
console.log(failed) // true
})
make<import ArrArr.type NonEmptyReadonlyArray<A> = readonly [
A,
...A[]
]
A readonly array guaranteed to have at least one element.
When to use
Use when non-emptiness must be tracked at the type level while preventing mutation.
Many Array module functions accept or return this type.
Example (Typing a non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
NonEmptyReadonlyArray<function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A> | typeof const scheduleStep: unique symbolscheduleStep, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E | import CauseCause.interface Done<A = void>A graceful completion signal for queues and streams.
When to use
Use to model normal producer completion through a stream or queue error
channel.
Details
Done indicates that a producer has finished normally — no more elements
will arrive. It is distinct from an error or interruption; it represents
successful completion. The optional value field can carry a final
leftover payload.
Example (Signaling queue completion)
import { Cause, Effect, Queue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* Queue.bounded<number, Cause.Done>(10)
yield* Queue.offer(queue, 1)
yield* Queue.end(queue)
const result = yield* Effect.flip(Queue.take(queue))
console.log(Cause.isDone(result)) // true
})
Companion namespace for the Done interface.
Creates a Done signal with an optional value.
When to use
Use when you need to construct a low-level pull completion signal directly.
Done<void>>({
capacity?: number | undefinedcapacity: 0
})
// upstream -> buffer
yield* const pull: Pull.Pull<
readonly [A, ...A[]],
E,
void,
R
>
const pull: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
pull.Pipeable.pipe<Pull.Pull<readonly [A, ...A[]], E, void, R>, Effect.Effect<readonly [A, ...A[]], Cause.Done<void> | E, R>, Effect.Effect<boolean, Cause.Done<void> | E, R>, Effect.Effect<never, Cause.Done<void> | E, R>, Effect.Effect<boolean, never, R>, Effect.Effect<Fiber.Fiber<boolean, never>, never, R>>(this: Pull.Pull<...>, ab: (_: Pull.Pull<readonly [A, ...A[]], E, void, R>) => Effect.Effect<readonly [A, ...A[]], Cause.Done<void> | E, R>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>, de: (_: Effect.Effect<...>) => Effect.Effect<...>, ef: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)pipe(
const pullLatch: Latch.Latchconst pullLatch: {
open: Effect.Effect<boolean>;
openUnsafe: (this: Latch) => boolean;
release: Effect.Effect<boolean>;
await: Effect.Effect<void>;
close: Effect.Effect<boolean>;
closeUnsafe: (this: Latch) => boolean;
whenOpen: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
isOpen: (this: Latch) => boolean;
}
pullLatch.Latch.whenOpen<A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>Runs the given effect only after the latch allows waiting fibers to
continue.
When to use
Use to gate an effect behind the latch signal.
whenOpen,
import EffectEffect.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>
}
flatMap((arr: readonly [A, ...A[]](parameter) arr: {
0: A;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A>>): Array<A>; (...items: Array<A | ConcatArray<A>>): Array<A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A>;
indexOf: (searchElement: A, fromIndex?: number) => number;
lastIndexOf: (searchElement: A, fromIndex?: number) => number;
every: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): Array<A> };
reduce: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
reduceRight: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
find: { (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findIndex: (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A>;
includes: (searchElement: A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A, index: number, array: Array<A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A | undefined;
findLast: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findLastIndex: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A>;
toSorted: (compareFn?: ((a: A, b: A) => number) | undefined) => Array<A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A>): Array<A>; (start: number, deleteCount?: number): Array<A> };
with: (index: number, value: A) => Array<A>;
}
arr) => {
const pullLatch: Latch.Latchconst pullLatch: {
open: Effect.Effect<boolean>;
openUnsafe: (this: Latch) => boolean;
release: Effect.Effect<boolean>;
await: Effect.Effect<void>;
close: Effect.Effect<boolean>;
closeUnsafe: (this: Latch) => boolean;
whenOpen: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
isOpen: (this: Latch) => boolean;
}
pullLatch.Latch.closeUnsafe(this: Latch): booleanCloses the latch synchronously so future waiters suspend again.
When to use
Use when synchronous code must close the latch immediately.
closeUnsafe()
return import QueueQueue.const offer: <A, E>(
self: Enqueue<A, E>,
message: Types.NoInfer<A>
) => Effect<boolean>
Adds a message to the queue. Returns false if the queue is done.
Details
For bounded queues, this operation may suspend if the queue is at capacity,
depending on the backpressure strategy. For dropping/sliding queues, it may
return false or succeed immediately by dropping/sliding existing messages.
Example (Offering a value)
import { Effect, Queue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* Queue.bounded<number>(3)
// Successfully add messages to queue
const success1 = yield* Queue.offer(queue, 1)
const success2 = yield* Queue.offer(queue, 2)
console.log(success1, success2) // true, true
// Queue state
const size = yield* Queue.size(queue)
console.log(size) // 2
})
offer(const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer, arr: readonly [A, ...A[]](parameter) arr: {
0: A;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A>>): Array<A>; (...items: Array<A | ConcatArray<A>>): Array<A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A>;
indexOf: (searchElement: A, fromIndex?: number) => number;
lastIndexOf: (searchElement: A, fromIndex?: number) => number;
every: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): Array<A> };
reduce: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
reduceRight: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
find: { (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findIndex: (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A>;
includes: (searchElement: A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A, index: number, array: Array<A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A | undefined;
findLast: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findLastIndex: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A>;
toSorted: (compareFn?: ((a: A, b: A) => number) | undefined) => Array<A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A>): Array<A>; (start: number, deleteCount?: number): Array<A> };
with: (index: number, value: A) => Array<A>;
}
arr)
}),
import EffectEffect.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>
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 second
const program = task.pipe(Effect.forever)
// This will run forever, without yielding every iteration
const programNoYield = task.pipe(Effect.forever({ disableYield: true }))
// Run for 5 seconds then interrupt
const timedProgram = Effect.gen(function*() {
const fiber = yield* Effect.forkChild(program)
yield* Effect.sleep("5 seconds")
yield* Fiber.interrupt(fiber)
})
forever, // don't disable autoYield to prevent choking the schedule
import EffectEffect.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>
}
catchCause((cause: Cause.Cause<Cause.Done<void> | E>(parameter) cause: {
reasons: ReadonlyArray<Reason<E>>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
cause) => import QueueQueue.const failCause: {
<E>(cause: Cause<E>): <A>(
self: Enqueue<A, E>
) => Effect<boolean>
<A, E>(
self: Enqueue<A, E>,
cause: Cause<E>
): Effect<boolean>
}
failCause(const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer, cause: Cause.Cause<Cause.Done<void> | E>(parameter) cause: {
reasons: ReadonlyArray<Reason<E>>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
cause)),
import EffectEffect.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>
}
forkIn(scope: Scope.Scope(parameter) scope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
scope)
)
// schedule -> buffer
let let lastOutput: Option.Option<B>lastOutput = import OptionOption.const none: <A = never>() => Option<A>Creates an Option representing the absence of a value.
When to use
Use to represent a missing or uninitialized value, such as returning "no
result" from a function.
Details
- Returns
Option<never>, which is a subtype of Option<A> for any A
- Always returns the same singleton instance
Example (Creating an empty Option)
import { Option } from "effect"
// ┌─── Option<never>
// ▼
const noValue = Option.none()
console.log(noValue)
// Output: { _id: 'Option', _tag: 'None' }
none<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B>()
let let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
leftover: import ArrArr.type NonEmptyReadonlyArray<A> = readonly [
A,
...A[]
]
A readonly array guaranteed to have at least one element.
When to use
Use when non-emptiness must be tracked at the type level while preventing mutation.
Many Array module functions accept or return this type.
Example (Typing a non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
NonEmptyReadonlyArray<function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2> | undefined
let let sinkHasInput: booleansinkHasInput = false
const const step: (
input: Option.Option<B>
) => Pull.Pull<C, E3, C, R3>
step = yield* import ScheduleSchedule.const toStepWithSleep: <
Output,
Input,
Error,
Env
>(
schedule: Schedule<Output, Input, Error, Env>
) => Effect<
(
input: Input
) => Pull.Pull<Output, Error, Output, Env>,
never,
Env
>
Extracts a step function from a Schedule that automatically handles sleep delays.
Example (Extracting a sleeping step function)
import { Effect, Schedule } from "effect"
// Convert schedule to step function with automatic sleeping
const schedule = Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 3 }))
const program = Effect.gen(function*() {
const stepWithSleep = yield* Schedule.toStepWithSleep(schedule)
// Each call will automatically sleep for the scheduled delay
console.log("Starting...")
const result1 = yield* stepWithSleep("first")
console.log(`First result: ${result1}`)
const result2 = yield* stepWithSleep("second")
console.log(`Second result: ${result2}`)
const result3 = yield* stepWithSleep("third")
console.log(`Third result: ${result3}`)
})
toStepWithSleep(schedule: Schedule.Schedule<
C,
Option.Option<B>,
E3,
R3
>
(parameter) schedule: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
schedule)
const const stepToBuffer: Effect.Effect<
never,
Cause.Done<void> | E3,
R3
>
const stepToBuffer: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
stepToBuffer = import EffectEffect.const suspend: <A, E, R>(
effect: LazyArg<Effect<A, E, R>>
) => Effect<A, E, R>
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: 0
console.log(Effect.runSync(bad)) // Output: 0
console.log(Effect.runSync(good)) // Output: 1
console.log(Effect.runSync(good)) // Output: 2
Example (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: 3524578
Example (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)
)
suspend(function function (local function) loop(): Pull.Pull<never, E3, void, R3>loop(): import PullPull.interface Pull<out A, out E = never, out Done = void, out R = never>An effectful pull step that either produces a value, fails with E, or
signals completion with Cause.Done<Done>.
When to use
Use to model one low-level pull step when a consumer repeatedly evaluates an
effect that may emit a value, fail normally, or signal normal completion
through Cause.Done.
Details
Pull represents completion in the error channel so low-level stream
consumers can distinguish ordinary failures from end-of-input and carry a
leftover value when needed.
Pull<never, function (type parameter) E3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E3, void, function (type parameter) R3 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>R3> {
return const step: (
input: Option.Option<B>
) => Pull.Pull<C, E3, C, R3>
step(let lastOutput: Option.Option<B>lastOutput).Pipeable.pipe<Pull.Pull<C, E3, C, R3>, Effect.Effect<boolean, Cause.Done<void> | E3 | Cause.Done<C>, R3>, Effect.Effect<never, Cause.Done<void> | E3 | Cause.Done<C>, R3>, Effect.Effect<never, Cause.Done<void> | Exclude<E3, Cause.Done<any>>, R3>>(this: Pull.Pull<...>, ab: (_: Pull.Pull<C, E3, C, R3>) => Effect.Effect<boolean, Cause.Done<void> | E3 | Cause.Done<C>, R3>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)pipe(
import EffectEffect.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>
}
flatMap(() => !let sinkHasInput: booleansinkHasInput ? function (local function) loop(): Pull.Pull<never, E3, void, R3>loop() : import QueueQueue.const offer: <A, E>(
self: Enqueue<A, E>,
message: Types.NoInfer<A>
) => Effect<boolean>
Adds a message to the queue. Returns false if the queue is done.
Details
For bounded queues, this operation may suspend if the queue is at capacity,
depending on the backpressure strategy. For dropping/sliding queues, it may
return false or succeed immediately by dropping/sliding existing messages.
Example (Offering a value)
import { Effect, Queue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* Queue.bounded<number>(3)
// Successfully add messages to queue
const success1 = yield* Queue.offer(queue, 1)
const success2 = yield* Queue.offer(queue, 2)
console.log(success1, success2) // true, true
// Queue state
const size = yield* Queue.size(queue)
console.log(size) // 2
})
offer(const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer, const scheduleStep: unique symbolscheduleStep)),
import EffectEffect.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>
}
flatMap(() => import EffectEffect.const never: Effect<never>const never: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
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 complete
const program = Effect.never
// This will run forever (or until interrupted)
// Effect.runPromise(program) // Never resolves
// Use with timeout for practical applications
const timedProgram = Effect.timeout(program, "1 second")
never),
import PullPull.const catchDone: {
<E, A2, E2, R2>(
f: (
leftover: Cause.Done.Extract<E>
) => Effect<A2, E2, R2>
): <A, R>(
self: Effect<A, E, R>
) => Effect<A | A2, ExcludeDone<E> | E2, R | R2>
<A, R, E, A2, E2, R2>(
self: Effect<A, E, R>,
f: (
leftover: Cause.Done.Extract<E>
) => Effect<A2, E2, R2>
): Effect<A | A2, ExcludeDone<E> | E2, R | R2>
}
catchDone(() => import CauseCause.const done: <A = void>(
value?: A
) => Effect.Effect<never, Done<A>>
Creates an Effect that fails with a Done error. Shorthand for
Effect.fail(Cause.Done(value)).
When to use
Use when you model stream or queue completion through the error channel.
Example (Failing with Done)
import { Cause, Effect } from "effect"
const program = Cause.done("finished")
Effect.runPromiseExit(program).then((exit) => {
console.log(exit._tag) // "Failure"
})
done())
)
})
// buffer -> sink
const const pullFromBuffer: Pull.Pull<
Arr.NonEmptyReadonlyArray<A>,
E
>
const pullFromBuffer: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
pullFromBuffer: import PullPull.interface Pull<out A, out E = never, out Done = void, out R = never>An effectful pull step that either produces a value, fails with E, or
signals completion with Cause.Done<Done>.
When to use
Use to model one low-level pull step when a consumer repeatedly evaluates an
effect that may emit a value, fail normally, or signal normal completion
through Cause.Done.
Details
Pull represents completion in the error channel so low-level stream
consumers can distinguish ordinary failures from end-of-input and carry a
leftover value when needed.
Pull<
import ArrArr.type NonEmptyReadonlyArray<A> = readonly [
A,
...A[]
]
A readonly array guaranteed to have at least one element.
When to use
Use when non-emptiness must be tracked at the type level while preventing mutation.
Many Array module functions accept or return this type.
Example (Typing a non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
NonEmptyReadonlyArray<function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A>,
function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E
> = import QueueQueue.const take: <A, E>(
self: Dequeue<A, E>
) => Effect<A, E>
Takes a single message from the queue, or wait for a message to be
available.
Details
If the queue is done, it will fail with Done. If the
queue fails, the Effect will fail with the error.
Example (Taking one value)
import { Cause, Effect, Queue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* Queue.bounded<string, Cause.Done>(3)
// Add some messages
yield* Queue.offer(queue, "first")
yield* Queue.offer(queue, "second")
// Take messages one by one
const msg1 = yield* Queue.take(queue)
const msg2 = yield* Queue.take(queue)
console.log(msg1, msg2) // "first", "second"
// End the queue
yield* Queue.end(queue)
// Taking from an ended queue fails with Done
const result = yield* Effect.match(Queue.take(queue), {
onFailure: (error: Cause.Done) => true,
onSuccess: (value: string) => false
})
console.log("Queue ended:", result) // true
})
take(const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer).Pipeable.pipe<Effect.Effect<readonly [A, ...A[]] | unique symbol, Cause.Done<void> | E, never>, Effect.Effect<readonly [A, ...A[]], Cause.Done<void> | E, never>>(this: Effect.Effect<readonly [A, ...A[]] | unique symbol, Cause.Done<void> | E, never>, ab: (_: Effect.Effect<readonly [A, ...A[]] | unique symbol, Cause.Done<void> | E, never>) => Effect.Effect<readonly [A, ...A[]], Cause.Done<void> | E, never>): Effect.Effect<readonly [A, ...A[]], Cause.Done<void> | E, never> (+21 overloads)pipe(
import EffectEffect.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>
}
flatMap((arr: readonly [A, ...A[]] | unique symbolarr) => {
if (arr: readonly [A, ...A[]] | unique symbolarr === const scheduleStep: unique symbolscheduleStep) {
return import CauseCause.const done: <A = void>(
value?: A
) => Effect.Effect<never, Done<A>>
Creates an Effect that fails with a Done error. Shorthand for
Effect.fail(Cause.Done(value)).
When to use
Use when you model stream or queue completion through the error channel.
Example (Failing with Done)
import { Cause, Effect } from "effect"
const program = Cause.done("finished")
Effect.runPromiseExit(program).then((exit) => {
console.log(exit._tag) // "Failure"
})
done()
}
let sinkHasInput: booleansinkHasInput = true
return import EffectEffect.const succeed: <A>(value: A) => Effect<A>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)
succeed(arr: readonly [A, ...A[]](parameter) arr: {
0: A;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A>>): Array<A>; (...items: Array<A | ConcatArray<A>>): Array<A> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A>;
indexOf: (searchElement: A, fromIndex?: number) => number;
lastIndexOf: (searchElement: A, fromIndex?: number) => number;
every: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A, index: number, array: ReadonlyArray<A>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): Array<A> };
reduce: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
reduceRight: { (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A): A; (callbackfn: (previousValue: A, currentValue: A, currentIndex: number, array: ReadonlyArray<A>) => A, initialValue: A): A; (callbac…;
find: { (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findIndex: (predicate: (value: A, index: number, obj: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A>;
includes: (searchElement: A, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A, index: number, array: Array<A>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A | undefined;
findLast: { (predicate: (value: A, index: number, array: ReadonlyArray<A>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any): A | undefined };
findLastIndex: (predicate: (value: A, index: number, array: ReadonlyArray<A>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A>;
toSorted: (compareFn?: ((a: A, b: A) => number) | undefined) => Array<A>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A>): Array<A>; (start: number, deleteCount?: number): Array<A> };
with: (index: number, value: A) => Array<A>;
}
arr)
})
)
const const sinkUpstream: Effect.Effect<
readonly [A | A2, ...(A | A2)[]],
Cause.Done<void> | E,
never
>
const sinkUpstream: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
sinkUpstream = import EffectEffect.const suspend: <A, E, R>(
effect: LazyArg<Effect<A, E, R>>
) => Effect<A, E, R>
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: 0
console.log(Effect.runSync(bad)) // Output: 0
console.log(Effect.runSync(good)) // Output: 1
console.log(Effect.runSync(good)) // Output: 2
Example (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: 3524578
Example (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)
)
suspend((): import PullPull.interface Pull<out A, out E = never, out Done = void, out R = never>An effectful pull step that either produces a value, fails with E, or
signals completion with Cause.Done<Done>.
When to use
Use to model one low-level pull step when a consumer repeatedly evaluates an
effect that may emit a value, fail normally, or signal normal completion
through Cause.Done.
Details
Pull represents completion in the error channel so low-level stream
consumers can distinguish ordinary failures from end-of-input and carry a
leftover value when needed.
Pull<import ArrArr.type NonEmptyReadonlyArray<A> = readonly [
A,
...A[]
]
A readonly array guaranteed to have at least one element.
When to use
Use when non-emptiness must be tracked at the type level while preventing mutation.
Many Array module functions accept or return this type.
Example (Typing a non-empty array)
import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
NonEmptyReadonlyArray<function (type parameter) A in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A | function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2>, function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E> => {
if (let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
leftover !== var undefinedundefined) {
const const chunk: readonly [A2, ...A2[]]const chunk: {
0: A2;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A2>>): Array<A2>; (...items: Array<A2 | ConcatArray<A2>>): Array<A2> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A2>;
indexOf: (searchElement: A2, fromIndex?: number) => number;
lastIndexOf: (searchElement: A2, fromIndex?: number) => number;
every: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A2, index: number, array: ReadonlyArray<A2>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A2, index: number, array: ReadonlyArray<A2>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): Array<A2> };
reduce: { (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2): A2; (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2, initialValue: A2): A…;
reduceRight: { (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2): A2; (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2, initialValue: A2): A…;
find: { (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => unknown, thisArg?: any): A2 | undefined };
findIndex: (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A2]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A2>;
includes: (searchElement: A2, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A2, index: number, array: Array<A2>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A2 | undefined;
findLast: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): A2 | undefined };
findLastIndex: (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A2>;
toSorted: (compareFn?: ((a: A2, b: A2) => number) | undefined) => Array<A2>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A2>): Array<A2>; (start: number, deleteCount?: number): Array<A2> };
with: (index: number, value: A2) => Array<A2>;
}
chunk = let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
let leftover: {
0: A2;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A2>>): Array<A2>; (...items: Array<A2 | ConcatArray<A2>>): Array<A2> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A2>;
indexOf: (searchElement: A2, fromIndex?: number) => number;
lastIndexOf: (searchElement: A2, fromIndex?: number) => number;
every: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A2, index: number, array: ReadonlyArray<A2>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A2, index: number, array: ReadonlyArray<A2>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): Array<A2> };
reduce: { (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2): A2; (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2, initialValue: A2): A…;
reduceRight: { (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2): A2; (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2, initialValue: A2): A…;
find: { (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => unknown, thisArg?: any): A2 | undefined };
findIndex: (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A2]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A2>;
includes: (searchElement: A2, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A2, index: number, array: Array<A2>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A2 | undefined;
findLast: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): A2 | undefined };
findLastIndex: (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A2>;
toSorted: (compareFn?: ((a: A2, b: A2) => number) | undefined) => Array<A2>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A2>): Array<A2>; (start: number, deleteCount?: number): Array<A2> };
with: (index: number, value: A2) => Array<A2>;
}
leftover
let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
leftover = var undefinedundefined
let sinkHasInput: booleansinkHasInput = true
return import EffectEffect.const succeed: <A>(value: A) => Effect<A>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)
succeed(const chunk: readonly [A2, ...A2[]]const chunk: {
0: A2;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<A2>>): Array<A2>; (...items: Array<A2 | ConcatArray<A2>>): Array<A2> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<A2>;
indexOf: (searchElement: A2, fromIndex?: number) => number;
lastIndexOf: (searchElement: A2, fromIndex?: number) => number;
every: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: A2, index: number, array: ReadonlyArray<A2>) => void, thisArg?: any) => void;
map: (callbackfn: (value: A2, index: number, array: ReadonlyArray<A2>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): Array<S>; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): Array<A2> };
reduce: { (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2): A2; (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2, initialValue: A2): A…;
reduceRight: { (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2): A2; (callbackfn: (previousValue: A2, currentValue: A2, currentIndex: number, array: ReadonlyArray<A2>) => A2, initialValue: A2): A…;
find: { (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => unknown, thisArg?: any): A2 | undefined };
findIndex: (predicate: (value: A2, index: number, obj: ReadonlyArray<A2>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, A2]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<A2>;
includes: (searchElement: A2, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: A2, index: number, array: Array<A2>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => A2 | undefined;
findLast: { (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => value is S, thisArg?: any): S | undefined; (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any): A2 | undefined };
findLastIndex: (predicate: (value: A2, index: number, array: ReadonlyArray<A2>) => unknown, thisArg?: any) => number;
toReversed: () => Array<A2>;
toSorted: (compareFn?: ((a: A2, b: A2) => number) | undefined) => Array<A2>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<A2>): Array<A2>; (start: number, deleteCount?: number): Array<A2> };
with: (index: number, value: A2) => Array<A2>;
}
chunk)
}
const pullLatch: Latch.Latchconst pullLatch: {
open: Effect.Effect<boolean>;
openUnsafe: (this: Latch) => boolean;
release: Effect.Effect<boolean>;
await: Effect.Effect<void>;
close: Effect.Effect<boolean>;
closeUnsafe: (this: Latch) => boolean;
whenOpen: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
isOpen: (this: Latch) => boolean;
}
pullLatch.Latch.openUnsafe(this: Latch): booleanOpens the latch synchronously, releasing all fibers waiting on it.
When to use
Use when synchronous code must open the latch immediately.
openUnsafe()
return const pullFromBuffer: Pull.Pull<
Arr.NonEmptyReadonlyArray<A>,
E
>
const pullFromBuffer: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
pullFromBuffer
})
const const catchSinkHalt: <E, R>(
self: Effect.Effect<Sink.End<B, A2>, E, R>
) => Effect.Effect<
[B, ...B[]],
Cause.Done<void> | E,
R
>
catchSinkHalt = import EffectEffect.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>
}
flatMap(([value: Bvalue, leftover_: readonly [A2, ...A2[]] | undefinedleftover_]: import SinkSink.type End<A, L = never> = readonly [
value: A,
leftover?: readonly [L, ...L[]] | undefined
]
Tuple returned when a Sink finishes.
Details
The first element is the sink result. The optional second element contains a
non-empty array of leftover input that was pulled but not consumed.
End<function (type parameter) B in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>B, function (type parameter) A2 in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>A2>) => {
// ignore the last output if the upstream only pulled a halt
if (!let sinkHasInput: booleansinkHasInput && const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer.Enqueue<in A, in E = never>.state: Queue.Queue.State<any, any>state._tag: "Done" | "Open" | "Closing"_tag === "Done") return import CauseCause.const done: <A = void>(
value?: A
) => Effect.Effect<never, Done<A>>
Creates an Effect that fails with a Done error. Shorthand for
Effect.fail(Cause.Done(value)).
When to use
Use when you model stream or queue completion through the error channel.
Example (Failing with Done)
import { Cause, Effect } from "effect"
const program = Cause.done("finished")
Effect.runPromiseExit(program).then((exit) => {
console.log(exit._tag) // "Failure"
})
done()
let lastOutput: Option.Option<B>lastOutput = import OptionOption.const some: <A>(value: A) => Option<A>Wraps the given value into an Option to represent its presence.
When to use
Use to wrap a known present value as Option
- Returning a successful result from a partial function
Details
- Always returns
Some<A>
- Does not filter
null or undefined; use
fromNullishOr
for that
Example (Wrapping a value)
import { Option } from "effect"
// ┌─── Option<number>
// ▼
const value = Option.some(1)
console.log(value)
// Output: { _id: 'Option', _tag: 'Some', value: 1 }
some(value: Bvalue)
let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
leftover = leftover_: readonly [A2, ...A2[]] | undefinedleftover_
return import EffectEffect.const succeed: <A>(value: A) => Effect<A>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)
succeed(import ArrArr.const of: <A>(a: A) => NonEmptyArray<A>Wraps a single value in a NonEmptyArray.
Example (Creating a single-element array)
import { Array } from "effect"
console.log(Array.of(1)) // [1]
of(value: Bvalue))
})
return import EffectEffect.const suspend: <A, E, R>(
effect: LazyArg<Effect<A, E, R>>
) => Effect<A, E, R>
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: 0
console.log(Effect.runSync(bad)) // Output: 0
console.log(Effect.runSync(good)) // Output: 1
console.log(Effect.runSync(good)) // Output: 2
Example (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: 3524578
Example (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)
)
suspend(() => {
// if the buffer has exited and there is no more data to process
if (const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer.Enqueue<in A, in E = never>.state: Queue.Queue.State<any, any>state._tag: "Done" | "Open" | "Closing"_tag === "Done" && let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
leftover === var undefinedundefined) {
return const buffer: Queue.Queue<
readonly [A, ...A[]] | unique symbol,
Cause.Done<void> | E
>
const buffer: {
strategy: "suspend" | "dropping" | "sliding";
dispatcher: SchedulerDispatcher;
capacity: number;
messages: MutableList.MutableList<any>;
state: Queue.State<any, any>;
scheduleRunning: boolean;
toString: () => string;
toJSON: () => unknown;
}
buffer.Enqueue<in A, in E = never>.state: {
readonly _tag: "Done";
readonly exit: Exit.Failure<never, any>;
}
state.exit: Failure<never, E>(property) exit: {
_tag: "Failure";
cause: Cause.Cause<E>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
exit as import ExitExit.type Exit<A, E = never> = Exit.Success<A, E> | Exit.Failure<A, E>Represents the result of an Effect computation.
When to use
Use when you need to synchronously inspect whether an Effect computation
succeeded or failed.
Details
An Exit<A, E> is either Success<A, E> containing a value of type A, or
Failure<A, E> containing a Cause<E> describing why the computation
failed.
Since Exit is also an Effect, you can yield it inside Effect.gen.
Example (Pattern matching on an Exit)
import { Exit } from "effect"
const success: Exit.Exit<number> = Exit.succeed(42)
const failure: Exit.Exit<number, string> = Exit.fail("error")
const result = Exit.match(success, {
onSuccess: (value) => `Got value: ${value}`,
onFailure: (cause) => `Got error: ${cause}`
})
Namespace containing helper types shared by Exit values.
When to use
Use to reference helper types that describe the shared structure of Exit
values.
Exit<never, import CauseCause.interface Done<A = void>A graceful completion signal for queues and streams.
When to use
Use to model normal producer completion through a stream or queue error
channel.
Details
Done indicates that a producer has finished normally — no more elements
will arrive. It is distinct from an error or interruption; it represents
successful completion. The optional value field can carry a final
leftover payload.
Example (Signaling queue completion)
import { Cause, Effect, Queue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* Queue.bounded<number, Cause.Done>(10)
yield* Queue.offer(queue, 1)
yield* Queue.end(queue)
const result = yield* Effect.flip(Queue.take(queue))
console.log(Cause.isDone(result)) // true
})
Companion namespace for the Done interface.
Creates a Done signal with an optional value.
When to use
Use when you need to construct a low-level pull completion signal directly.
Done<void> | function (type parameter) E in <A, E, R, B, A2, E2, R2, C, E3, R3>(self: Stream<A, E, R>, sink: Sink.Sink<B, A | A2, A2, E2, R2>, schedule: Schedule.Schedule<C, Option.Option<B>, E3, R3>): Stream<B, E | E2 | E3, R | R2 | R3>E>
}
let sinkHasInput: booleansinkHasInput = let leftover:
| Arr.NonEmptyReadonlyArray<A2>
| undefined
leftover !== var undefinedundefined
return import EffectEffect.const succeed: <A>(value: A) => Effect<A>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)
succeed(import EffectEffect.const suspend: <A, E, R>(
effect: LazyArg<Effect<A, E, R>>
) => Effect<A, E, R>
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: 0
console.log(Effect.runSync(bad)) // Output: 0
console.log(Effect.runSync(good)) // Output: 1
console.log(Effect.runSync(good)) // Output: 2
Example (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: 3524578
Example (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)
)
suspend(() => sink: Sink.Sink<B, A | A2, A2, E2, R2>(parameter) sink: {
transform: (upstream: Pull.Pull<NonEmptyReadonlyArray<In>, never, void>, scope: Scope.Scope) => Effect.Effect<End<A, L>, E, R>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
sink.Sink<B, A | A2, A2, E2, R2>.transform: (upstream: Pull.Pull<NonEmptyReadonlyArray<In>, never, void>, scope: Scope.Scope) => Effect.Effect<End<A, L>, E, R>transform(const sinkUpstream: Effect.Effect<
readonly [A | A2, ...(A | A2)[]],
Cause.Done<void> | E,
never
>
const sinkUpstream: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
sinkUpstream as any, scope: Scope.Scope(parameter) scope: {
strategy: "sequential" | "parallel";
state: State.Open | State.Closed | State.Empty;
}
scope)))
}).Pipeable.pipe<Effect.Effect<Effect.Effect<Sink.End<B, A2>, E2, R2>, Cause.Done<void> | E, never>, Effect.Effect<[B, ...B[]], Cause.Done<void> | E | E2 | E3, R2 | R3>>(this: Effect.Effect<Effect.Effect<Sink.End<B, A2>, E2, R2>, Cause.Done<...> | E, never>, ab: (_: Effect.Effect<Effect.Effect<Sink.End<B, A2>, E2, R2>, Cause.Done<void> | E, never>) => Effect.Effect<[B, ...B[]], Cause.Done<void> | E | E2 | E3, R2 | R3>): Effect.Effect<...> (+21 overloads)pipe(
import EffectEffect.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>
}
flatMap((pull: Effect.Effect<Sink.End<B, A2>, E2, R2>(parameter) pull: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
pull) => import EffectEffect.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>
}
raceFirst(const catchSinkHalt: <E2, R2>(
self: Effect.Effect<Sink.End<B, A2>, E2, R2>
) => Effect.Effect<
[B, ...B[]],
Cause.Done<void> | E2,
R2
>
catchSinkHalt(pull: Effect.Effect<Sink.End<B, A2>, E2, R2>(parameter) pull: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
pull), const stepToBuffer: Effect.Effect<
never,
Cause.Done<void> | E3,
R3
>
const stepToBuffer: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
stepToBuffer))
)
}))))