///
/**
* Describes workflows that run only when executed by the Effect runtime.
*
* An `Effect` can succeed with an `A`, fail with an `E`, and require
* services `R`. Creating an effect does not perform the work; it builds a value
* that can be composed, provided with services, retried, interrupted, run
* concurrently, or inspected by the runtime. This module is the main API for
* creating effects, combining them, handling failures, managing resources, and
* running effect programs.
*
* @stability stable
* @since 2.0.0
*/
import type * as Arr from "./Array.ts"
import type * as Cause from "./Cause.ts"
import type { Clock } from "./Clock.ts"
import * as Context from "./Context.ts"
import * as Duration from "./Duration.ts"
import type * as ExecutionPlan from "./ExecutionPlan.ts"
import * as Exit from "./Exit.ts"
import type { Fiber } from "./Fiber.ts"
import type * as Filter from "./Filter.ts"
import { dual, type LazyArg } from "./Function.ts"
import type { TypeLambda } from "./HKT.ts"
import type { Inspectable } from "./Inspectable.ts"
import * as core from "./internal/core.ts"
import * as internal from "./internal/effect.ts"
import * as internalExecutionPlan from "./internal/executionPlan.ts"
import * as internalLayer from "./internal/layer.ts"
import * as InternalRecord from "./internal/record.ts"
import * as internalRequest from "./internal/request.ts"
import * as internalSchedule from "./internal/schedule.ts"
import type * as Layer from "./Layer.ts"
import type { Logger } from "./Logger.ts"
import type { Severity } from "./LogLevel.ts"
import * as Metric from "./Metric.ts"
import type { Option } from "./Option.ts"
import type { Pipeable } from "./Pipeable.ts"
import type * as Predicate from "./Predicate.ts"
import { CurrentLogAnnotations, CurrentLogSpans } from "./References.ts"
import type * as Request from "./Request.ts"
import type { RequestResolver } from "./RequestResolver.ts"
import type * as Result from "./Result.ts"
import type { Metadata as ScheduleMetadata, Schedule } from "./Schedule.ts"
import type { Scheduler } from "./Scheduler.ts"
import type { Scope } from "./Scope.ts"
import type {
AnySpan,
ParentSpan,
Span,
SpanLink,
SpanOptions,
SpanOptionsNoTrace,
TraceOptions,
Tracer
} from "./Tracer.ts"
import type { TxRef } from "./TxRef.ts"
import type {
Concurrency,
Covariant,
EqualsWith,
ExcludeReason,
ExcludeTag,
ExtractReason,
ExtractTag,
NarrowReason,
NoInfer,
OmitReason,
ReasonOf,
ReasonTags,
Simplify,
Tags,
unassigned
} from "./Types.ts"
import type * as Unify from "./Unify.ts"
/**
* Type-level identifier for `Effect` values.
*
* @stability stable
* @category type IDs
* @since 4.0.0
*/
export type TypeId = "~effect/Effect"
/**
* Runtime identifier used to recognize `Effect` values.
*
* @stability stable
* @category type IDs
* @since 4.0.0
*/
export const TypeId: TypeId = core.EffectTypeId
/**
* The `Effect` interface defines a value that lazily describes a workflow or
* job. The workflow requires some context `R`, and may fail with an error of
* type `E`, or succeed with a value of type `A`.
*
* **When to use**
*
* Use when you need to represent a lazy, composable workflow that can require
* services, fail with a typed error, or succeed with a typed value.
*
* **Details**
*
* `Effect` values model resourceful interaction with the outside world,
* including synchronous, asynchronous, concurrent, and parallel interaction.
* They use a fiber-based concurrency model, with built-in support for
* scheduling, fine-grained interruption, structured concurrency, and high
* scalability.
*
* To run an `Effect` value, you need a `Runtime`, which is a type that is
* capable of executing `Effect` values.
*
* @stability stable
* @category models
* @since 2.0.0
*/
export interface Effect extends Pipeable, Inspectable {
readonly [TypeId]: Variance
[Symbol.iterator](): EffectIterator>
[Unify.typeSymbol]?: unknown
[Unify.unifySymbol]?: EffectUnify
[Unify.ignoreSymbol]?: {}
}
/**
* Type-level unification support for `Effect` values.
*
* @stability stable
* @category models
* @since 2.0.0
*/
export interface EffectUnify {
Effect?: () => A[Unify.typeSymbol] extends
| Effect
| infer _ ? Effect
: never
}
/**
* Type lambda used to represent `Effect` in higher-kinded APIs.
*
* @stability stable
* @category utility types
* @since 2.0.0
*/
export interface EffectTypeLambda extends TypeLambda {
readonly type: Effect
}
/**
* Variance interface for Effect, encoding the type parameters' variance.
*
* @stability stable
* @category models
* @since 2.0.0
*/
export interface Variance {
_A: Covariant
_E: Covariant
_R: Covariant
}
/**
* Extracts the success type from an `Effect`.
*
* **When to use**
*
* Use to derive the value produced by an existing effect when declaring
* reusable type aliases, service interfaces, or function signatures.
*
* @see {@link Error} for extracting the failure type from the same `Effect`
* @see {@link Services} for extracting the required services from the same `Effect`
*
* @stability stable
* @category utility types
* @since 2.0.0
*/
export type Success = T extends Effect ? _A
: never
/**
* Extracts the error type from an `Effect`.
*
* **When to use**
*
* Use to derive the error type from an existing `Effect` type when declaring
* helper types, wrappers, or APIs that preserve the effect's failure channel.
*
* **Details**
*
* Non-`Effect` inputs resolve to `never`.
*
* @see {@link Success} for extracting the success value type instead
* @see {@link Services} for extracting the required services type instead
*
* @stability stable
* @category utility types
* @since 2.0.0
*/
export type Error = T extends Effect ? _E
: never
/**
* Extracts the required services type from an `Effect`.
*
* **When to use**
*
* Use to derive the context requirements of a generic or inferred `Effect`
* without restating its `R` type parameter.
*
* @see {@link Success} for extracting the success value type instead
* @see {@link Error} for extracting the failure type instead
*
* @stability stable
* @category utility types
* @since 4.0.0
*/
export type Services = T extends Effect ? _R
: never
/**
* Checks whether a value is an `Effect`.
*
* **Example** (Checking whether a value is an Effect)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* Effect.isEffect(Effect.succeed(1)) // => true
* Effect.isEffect("hello") // => false
* ```
*
* @stability stable
* @category guards
* @since 2.0.0
*/
export const isEffect: (u: unknown) => u is Effect = core.isEffect
/**
* Iterator interface for Effect generators, enabling Effect values to work with generator functions.
*
* **When to use**
*
* Use when defining or typing `[Symbol.iterator]()` for values typed as
* `Effect`s so `yield*` can pass their success type back into `Effect.gen`.
*
* @see {@link gen} for writing generator-based `Effect` programs that consume this iterator protocol
*
* @stability stable
* @category models
* @since 4.0.0
*/
export interface EffectIterator> {
next(
...args: ReadonlyArray
): IteratorResult>
}
// ========================================================================
// Collecting
// ========================================================================
/**
* Namespace containing type utilities for the `Effect.all` function, which handles
* collecting multiple effects into various output structures.
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
export declare namespace All {
/**
* Alias for any `Effect` value accepted by `Effect.all`.
*
* @category utility types
* @since 2.0.0
*/
export type EffectAny = Effect
/**
* Computes the return type for `Effect.all` when collecting an iterable.
*
* @category utility types
* @since 2.0.0
*/
export type ReturnIterable<
T extends Iterable,
Discard extends boolean,
Mode extends boolean = false
> = [T] extends [Iterable>] ? Effect<
Discard extends true ? void : Array : A>,
Mode extends true ? never : E,
R
>
: never
/**
* Computes the return type for `Effect.all` when collecting a tuple.
*
* @category utility types
* @since 2.0.0
*/
export type ReturnTuple<
T extends ReadonlyArray,
Discard extends boolean,
Mode extends boolean = false
> = Effect<
Discard extends true ? void
: T[number] extends never ? []
: {
-readonly [K in keyof T]: T[K] extends Effect<
infer _A,
infer _E,
infer _R
> ? Mode extends true ? Result.Result<_A, _E> : _A
: never
},
Mode extends true ? never
: T[number] extends never ? never
: T[number] extends Effect ? _E
: never,
T[number] extends never ? never
: T[number] extends Effect ? _R
: never
> extends infer X ? X
: never
/**
* Computes the return type for `Effect.all` when collecting a record.
*
* @category utility types
* @since 2.0.0
*/
export type ReturnObject = [T] extends [
Record
] ? Effect<
Discard extends true ? void
: {
-readonly [K in keyof T]: [T[K]] extends [
Effect
] ? Mode extends true ? Result.Result<_A, _E> : _A
: never
},
Mode extends true ? never : Error>,
Services>
>
: never
/**
* Detects whether `Effect.all` should discard collected values.
*
* @category utility types
* @since 2.0.0
*/
export type IsDiscard = [Extract] extends [
never
] ? false
: true
/**
* Detects whether `Effect.all` should collect results in `Result` mode.
*
* @category utility types
* @since 4.0.0
*/
export type IsResult = [Extract] extends [never] ? false : true
/**
* Computes the return type for `Effect.all` from its input and options.
*
* @category utility types
* @since 2.0.0
*/
export type Return<
Arg extends Iterable | Record,
O extends {
readonly concurrency?: Concurrency | undefined
readonly discard?: boolean | undefined
readonly mode?: "default" | "result" | undefined
}
> = [Arg] extends [ReadonlyArray] ? ReturnTuple, IsResult>
: [Arg] extends [Iterable] ? ReturnIterable, IsResult>
: [Arg] extends [Record] ? ReturnObject, IsResult>
: never
type ObjectValues = T extends unknown ? T[keyof T] : never
}
/**
* Combines an iterable or record of effects into one effect whose success shape
* follows the input.
*
* **When to use**
*
* Use to run a known collection of effects and collect results in the same
* tuple, iterable, or record shape.
*
* **Details**
*
* Tuple and iterable inputs collect results in order. Record inputs collect
* results under the same keys. By default, the combined effect fails on the
* first failure; with concurrent execution, effects that have already started
* may be interrupted, while effects not yet started are skipped.
*
* Options:
*
* Use `concurrency` to control sequential or concurrent execution. Use
* `mode: "result"` to run every effect and collect each success or failure as a
* `Result` in the same output shape. Use `discard: true` to ignore successful
* values and return `void`.
*
* **Example** (Collecting tuple results in order)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const tupleOfEffects = [
* Effect.succeed(42),
* Effect.succeed("Hello")
* ] as const
*
* // ┌─── Effect<[number, string], never, never>
* // ▼
* const resultsAsTuple = Effect.all(tupleOfEffects)
*
* await Effect.runPromise(resultsAsTuple) // => [42, "Hello"]
* ```
*
* **Example** (Collecting iterable results in order)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const iterableOfEffects: Iterable> = [1, 2, 3].map(
* Effect.succeed
* )
*
* // ┌─── Effect
* // ▼
* const resultsAsArray = Effect.all(iterableOfEffects)
*
* await Effect.runPromise(resultsAsArray) // => [1, 2, 3]
* ```
*
* **Example** (Collecting struct results by key)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const structOfEffects = {
* a: Effect.succeed(42),
* b: Effect.succeed("Hello")
* }
*
* // ┌─── Effect<{ a: number; b: string; }, never, never>
* // ▼
* const resultsAsStruct = Effect.all(structOfEffects)
*
* await Effect.runPromise(resultsAsStruct) // => { a: 42, b: "Hello" }
* ```
*
* **Example** (Collecting record results by key)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const recordOfEffects: Record> = {
* key1: Effect.succeed(1),
* key2: Effect.succeed(2)
* }
*
* // ┌─── Effect<{ [x: string]: number; }, never, never>
* // ▼
* const resultsAsRecord = Effect.all(recordOfEffects)
*
* await Effect.runPromise(resultsAsRecord) // => { key1: 1, key2: 2 }
* ```
*
* **Example** (Stopping on the first failure)
*
* ```ts import.meta.vitest
* import { Effect, Exit } from "effect"
* const output: Array = []
* const record = (value: unknown) => Effect.sync(() => { output.push(value) })
*
* const program = Effect.all([
* Effect.succeed("Task1").pipe(Effect.tap(record)),
* Effect.fail("Task2: Oh no!").pipe(Effect.tap(record)),
* // Won't execute due to earlier failure
* Effect.succeed("Task3").pipe(Effect.tap(record))
* ])
*
* const outcome = await Effect.runPromiseExit(program)
* const observation = [output, outcome] // => [["Task1"], Exit.fail("Task2: Oh no!")]
* ```
*
* @see {@link forEach} for iterating over elements and applying an effect.
* @stability stable
* @category collecting
* @since 2.0.0
*/
export const all: <
const Arg extends
| Iterable>
| Record>,
O extends {
readonly concurrency?: Concurrency | undefined
readonly discard?: boolean | undefined
readonly mode?: "default" | "result" | undefined
}
>(
arg: Arg,
options?: O
) => All.Return = internal.all
/**
* Applies an effectful function to each element and partitions successes and
* failures.
*
* **Details**
*
* The returned tuple is `[passes, fails]`, where `passes` contains all
* successes and `fails` contains all failures.
*
* This function runs every effect and never fails. Use `concurrency` to control
* parallelism.
*
* **Example** (Separating successes and failures)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const program = Effect.partition([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromise(program) // => [[1, 3], ['0 is even', '2 is even']]
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
export const partition: {
/**
* Applies an effectful function to each element and partitions successes and
* failures.
*
* **Details**
*
* The returned tuple is `[passes, fails]`, where `passes` contains all
* successes and `fails` contains all failures.
*
* This function runs every effect and never fails. Use `concurrency` to control
* parallelism.
*
* **Example** (Separating successes and failures)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const program = Effect.partition([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromise(program) // => [[1, 3], ['0 is even', '2 is even']]
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
f: (a: A, i: number) => Effect,
options?: { readonly concurrency?: Concurrency | undefined }
): (elements: Iterable) => Effect<[passes: Array, fails: Array], never, R>
/**
* Applies an effectful function to each element and partitions successes and
* failures.
*
* **Details**
*
* The returned tuple is `[passes, fails]`, where `passes` contains all
* successes and `fails` contains all failures.
*
* This function runs every effect and never fails. Use `concurrency` to control
* parallelism.
*
* **Example** (Separating successes and failures)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
*
* const program = Effect.partition([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromise(program) // => [[1, 3], ['0 is even', '2 is even']]
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
elements: Iterable,
f: (a: A, i: number) => Effect,
options?: { readonly concurrency?: Concurrency | undefined }
): Effect<[passes: Array, fails: Array], never, R>
} = internal.partition
/**
* Reduces elements from left to right with an effectful accumulator function.
*
* **When to use**
*
* Use when each accumulation step is effectful and must run sequentially in
* iteration order.
*
* **Details**
*
* The accumulator function receives the current accumulator, the current
* element, and its zero-based index. The `zero` function is evaluated each
* time the effect runs. An empty iterable succeeds with its result. If a step
* fails, remaining elements are not processed.
*
* **Example** (Summing values sequentially)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
* const output: Array = []
*
* const program = Effect.reduce(
* [1, 2, 3],
* () => 0,
* (total, value, index) =>
* Effect.sync(() => { output.push(`Adding ${value} at index ${index}`) }).pipe(
* Effect.as(total + value)
* )
* )
*
* void output.push(await Effect.runPromise(program))
* output // => ["Adding 1 at index 0", "Adding 2 at index 1", "Adding 3 at index 2", 6]
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
export const reduce: {
/**
* Reduces elements from left to right with an effectful accumulator function.
*
* **When to use**
*
* Use when each accumulation step is effectful and must run sequentially in
* iteration order.
*
* **Details**
*
* The accumulator function receives the current accumulator, the current
* element, and its zero-based index. The `zero` function is evaluated each
* time the effect runs. An empty iterable succeeds with its result. If a step
* fails, remaining elements are not processed.
*
* **Example** (Summing values sequentially)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
* const output: Array = []
*
* const program = Effect.reduce(
* [1, 2, 3],
* () => 0,
* (total, value, index) =>
* Effect.sync(() => { output.push(`Adding ${value} at index ${index}`) }).pipe(
* Effect.as(total + value)
* )
* )
*
* void output.push(await Effect.runPromise(program))
* output // => ["Adding 1 at index 0", "Adding 2 at index 1", "Adding 3 at index 2", 6]
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(zero: LazyArg, f: (z: Z, a: A, i: number) => Effect): (elements: Iterable) => Effect
/**
* Reduces elements from left to right with an effectful accumulator function.
*
* **When to use**
*
* Use when each accumulation step is effectful and must run sequentially in
* iteration order.
*
* **Details**
*
* The accumulator function receives the current accumulator, the current
* element, and its zero-based index. The `zero` function is evaluated each
* time the effect runs. An empty iterable succeeds with its result. If a step
* fails, remaining elements are not processed.
*
* **Example** (Summing values sequentially)
*
* ```ts import.meta.vitest
* import { Effect } from "effect"
* const output: Array = []
*
* const program = Effect.reduce(
* [1, 2, 3],
* () => 0,
* (total, value, index) =>
* Effect.sync(() => { output.push(`Adding ${value} at index ${index}`) }).pipe(
* Effect.as(total + value)
* )
* )
*
* void output.push(await Effect.runPromise(program))
* output // => ["Adding 1 at index 0", "Adding 2 at index 1", "Adding 3 at index 2", 6]
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
elements: Iterable,
zero: LazyArg,
f: (z: Z, a: A, i: number) => Effect
): Effect
} = internal.reduce
/**
* Applies an effectful function to each element and accumulates all failures.
*
* **Details**
*
* This function always evaluates every element. If at least one effect fails,
* all failures are returned as a non-empty array and successes are discarded.
* If all effects succeed, it returns all collected successes.
*
* Use `discard: true` to ignore successful values while still validating all
* elements.
*
* **Example** (Validating every element)
*
* ```ts import.meta.vitest
* import { Effect, Exit } from "effect"
*
* const program = Effect.validate([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromiseExit(program) // => Exit.fail(["0 is even", "2 is even"])
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
export const validate: {
/**
* Applies an effectful function to each element and accumulates all failures.
*
* **Details**
*
* This function always evaluates every element. If at least one effect fails,
* all failures are returned as a non-empty array and successes are discarded.
* If all effects succeed, it returns all collected successes.
*
* Use `discard: true` to ignore successful values while still validating all
* elements.
*
* **Example** (Validating every element)
*
* ```ts import.meta.vitest
* import { Effect, Exit } from "effect"
*
* const program = Effect.validate([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromiseExit(program) // => Exit.fail(["0 is even", "2 is even"])
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
f: (a: A, i: number) => Effect,
options?: {
readonly concurrency?: Concurrency | undefined
readonly discard?: false | undefined
} | undefined
): (elements: Iterable) => Effect, Arr.NonEmptyArray, R>
/**
* Applies an effectful function to each element and accumulates all failures.
*
* **Details**
*
* This function always evaluates every element. If at least one effect fails,
* all failures are returned as a non-empty array and successes are discarded.
* If all effects succeed, it returns all collected successes.
*
* Use `discard: true` to ignore successful values while still validating all
* elements.
*
* **Example** (Validating every element)
*
* ```ts import.meta.vitest
* import { Effect, Exit } from "effect"
*
* const program = Effect.validate([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromiseExit(program) // => Exit.fail(["0 is even", "2 is even"])
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
f: (a: A, i: number) => Effect,
options: {
readonly concurrency?: Concurrency | undefined
readonly discard: true
}
): (elements: Iterable) => Effect, R>
/**
* Applies an effectful function to each element and accumulates all failures.
*
* **Details**
*
* This function always evaluates every element. If at least one effect fails,
* all failures are returned as a non-empty array and successes are discarded.
* If all effects succeed, it returns all collected successes.
*
* Use `discard: true` to ignore successful values while still validating all
* elements.
*
* **Example** (Validating every element)
*
* ```ts import.meta.vitest
* import { Effect, Exit } from "effect"
*
* const program = Effect.validate([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromiseExit(program) // => Exit.fail(["0 is even", "2 is even"])
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
elements: Iterable,
f: (a: A, i: number) => Effect,
options?: {
readonly concurrency?: Concurrency | undefined
readonly discard?: false | undefined
} | undefined
): Effect, Arr.NonEmptyArray, R>
/**
* Applies an effectful function to each element and accumulates all failures.
*
* **Details**
*
* This function always evaluates every element. If at least one effect fails,
* all failures are returned as a non-empty array and successes are discarded.
* If all effects succeed, it returns all collected successes.
*
* Use `discard: true` to ignore successful values while still validating all
* elements.
*
* **Example** (Validating every element)
*
* ```ts import.meta.vitest
* import { Effect, Exit } from "effect"
*
* const program = Effect.validate([0, 1, 2, 3], (n) =>
* n % 2 === 0 ? Effect.fail(`${n} is even`) : Effect.succeed(n)
* )
*
* await Effect.runPromiseExit(program) // => Exit.fail(["0 is even", "2 is even"])
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(
elements: Iterable,
f: (a: A, i: number) => Effect,
options: {
readonly concurrency?: Concurrency | undefined
readonly discard: true
}
): Effect, R>
} = internal.validate
/**
* Returns the first element that satisfies an effectful predicate.
*
* **Details**
*
* The predicate receives the element and its index. Evaluation short-circuits
* as soon as an element matches.
*
* **Example** (Finding the first successful match)
*
* ```ts import.meta.vitest
* import { Effect, Option } from "effect"
*
* const program = Effect.findFirst([1, 2, 3, 4], (n) => Effect.succeed(n > 2))
*
* await Effect.runPromise(program) // => Option.some(3)
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
export const findFirst: {
/**
* Returns the first element that satisfies an effectful predicate.
*
* **Details**
*
* The predicate receives the element and its index. Evaluation short-circuits
* as soon as an element matches.
*
* **Example** (Finding the first successful match)
*
* ```ts import.meta.vitest
* import { Effect, Option } from "effect"
*
* const program = Effect.findFirst([1, 2, 3, 4], (n) => Effect.succeed(n > 2))
*
* await Effect.runPromise(program) // => Option.some(3)
* ```
*
* @stability stable
* @category collecting
* @since 2.0.0
*/
(predicate: (a: NoInfer, i: number) => Effect): (elements: Iterable) => Effect