Console.error

Many of the other standard console methods have Effectful equivalents in Console. Console.error behaves very similarly to Console.log (44) .

import {
import Console
Console
,
import Data
Data
,
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect";
class
class ValidationError
ValidationError
extends
import Data
Data
.
const TaggedError: <"ValidationError">(tag: "ValidationError") => new <A>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & ... 1 more ... & Readonly<...>

@since2.0.0

TaggedError
("ValidationError")<{
message: string
message
: string;
}> {}
const
const COMMON_PASSWORDS: Set<string>
COMMON_PASSWORDS
= new
var Set: SetConstructor
new <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set
(["password", "changeme", "12345678"]);
const
const isValidPassword: (password: string) => Effect.Effect<undefined, ValidationError, never>
isValidPassword
= (
password: string
password
: string) =>
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<never, ValidationError, never>>, undefined>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<never, ValidationError, never>>, undefined, never>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
if (
password: string
password
.
String.length: number

Returns the length of a String object.

length
< 8) {
return yield* new
constructor ValidationError<{
message: string;
}>(args: {
readonly message: string;
}): ValidationError
ValidationError
({
message: string
message
: "Password must be at least 8 characters",
});
}
if (
const COMMON_PASSWORDS: Set<string>
COMMON_PASSWORDS
.
Set<string>.has(value: string): boolean

@returnsa boolean indicating whether an element with the specified value exists in the Set or not.

has
(
password: string
password
.
String.toLowerCase(): string

Converts all the alphabetic characters in a string to lowercase.

toLowerCase
())) {
return yield* new
constructor ValidationError<{
message: string;
}>(args: {
readonly message: string;
}): ValidationError
ValidationError
({
message: string
message
: "Password must not be a common password",
});
}
});
const
const password1: Effect.Effect<void, never, never>
password1
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("trying first password").
Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<undefined, ValidationError, never>, Effect.Effect<void, ValidationError, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <undefined, ValidationError, never>(that: Effect.Effect<undefined, ValidationError, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
const isValidPassword: (password: string) => Effect.Effect<undefined, ValidationError, never>
isValidPassword
("short")),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("first password OK")),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchAll: <ValidationError, void, never, never>(f: (e: ValidationError) => Effect.Effect<void, never, never>) => <A, R>(self: Effect.Effect<A, ValidationError, R>) => Effect.Effect<...> (+1 overload)

Handles all errors in an effect by providing a fallback effect.

Details

This function catches any errors that may occur during the execution of an effect and allows you to handle them by specifying a fallback effect. This ensures that the program continues without failing by recovering from errors using the provided fallback logic.

Note: This function only handles recoverable errors. It will not recover from unrecoverable defects.

Example (Providing Recovery Logic for Recoverable Errors)

import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = program.pipe(
Effect.catchAll((error) =>
Effect.succeed(`Recovering from ${error._tag}`)
)
)

@seecatchAllCause for a version that can recover from both recoverable and unrecoverable errors.

@since2.0.0

catchAll
((
e: ValidationError
e
) =>
import Console
Console
.
const error: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

error
(
e: ValidationError
e
.
message: string
message
))
);
const
const password2: Effect.Effect<void, never, never>
password2
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("trying second password").
Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<undefined, ValidationError, never>, Effect.Effect<void, ValidationError, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <undefined, ValidationError, never>(that: Effect.Effect<undefined, ValidationError, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
const isValidPassword: (password: string) => Effect.Effect<undefined, ValidationError, never>
isValidPassword
("12345678")),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("second password OK")),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchTag: <"ValidationError", ValidationError, void, never, never>(k: "ValidationError", f: (e: ValidationError) => Effect.Effect<void, never, never>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Catches and handles specific errors by their _tag field, which is used as a discriminator.

When to Use

catchTag is useful when your errors are tagged with a readonly _tag field that identifies the error type. You can use this function to handle specific error types by matching the _tag value. This allows for precise error handling, ensuring that only specific errors are caught and handled.

The error type must have a readonly _tag field to use catchTag. This field is used to identify and match errors.

Example (Handling Errors by Tag)

import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, ValidationError, never>
// ▼
const recovered = program.pipe(
// Only handle HttpError errors
Effect.catchTag("HttpError", (_HttpError) =>
Effect.succeed("Recovering from HttpError")
)
)

@seecatchTags for a version that allows you to handle multiple error types at once.

@since2.0.0

catchTag
("ValidationError", (
e: ValidationError
e
) =>
import Console
Console
.
const error: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

error
(
e: ValidationError
e
.
message: string
message
))
);
const
const password3: Effect.Effect<void, never, never>
password3
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("trying third password").
Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<undefined, ValidationError, never>, Effect.Effect<void, ValidationError, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <undefined, ValidationError, never>(that: Effect.Effect<undefined, ValidationError, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
const isValidPassword: (password: string) => Effect.Effect<undefined, ValidationError, never>
isValidPassword
("kookaburra")),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("third password OK")),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const catchAll: <ValidationError, void, never, never>(f: (e: ValidationError) => Effect.Effect<void, never, never>) => <A, R>(self: Effect.Effect<A, ValidationError, R>) => Effect.Effect<...> (+1 overload)

Handles all errors in an effect by providing a fallback effect.

Details

This function catches any errors that may occur during the execution of an effect and allows you to handle them by specifying a fallback effect. This ensures that the program continues without failing by recovering from errors using the provided fallback logic.

Note: This function only handles recoverable errors. It will not recover from unrecoverable defects.

Example (Providing Recovery Logic for Recoverable Errors)

import { Effect, Random } from "effect"
class HttpError {
readonly _tag = "HttpError"
}
class ValidationError {
readonly _tag = "ValidationError"
}
// ┌─── Effect<string, HttpError | ValidationError, never>
// ▼
const program = Effect.gen(function* () {
const n1 = yield* Random.next
const n2 = yield* Random.next
if (n1 < 0.5) {
yield* Effect.fail(new HttpError())
}
if (n2 < 0.5) {
yield* Effect.fail(new ValidationError())
}
return "some result"
})
// ┌─── Effect<string, never, never>
// ▼
const recovered = program.pipe(
Effect.catchAll((error) =>
Effect.succeed(`Recovering from ${error._tag}`)
)
)

@seecatchAllCause for a version that can recover from both recoverable and unrecoverable errors.

@since2.0.0

catchAll
((
e: ValidationError
e
) =>
import Console
Console
.
const error: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

error
(
e: ValidationError
e
.
message: string
message
))
);
const
const program: Effect.Effect<void, never, never>
program
=
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("starting").
Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<void, never, never>, Effect.Effect<void, never, never>, Effect.Effect<void, never, never>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>, bc: (_: Effect.Effect<...>) => Effect.Effect<...>, cd: (_: Effect.Effect<...>) => Effect.Effect<...>, de: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
const password1: Effect.Effect<void, never, never>
password1
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
const password2: Effect.Effect<void, never, never>
password2
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
const password3: Effect.Effect<void, never, never>
password3
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const zipRight: <void, never, never>(that: Effect.Effect<void, never, never>, options?: {
readonly concurrent?: boolean | undefined;
readonly batching?: boolean | "inherit" | undefined;
readonly concurrentFinalizers?: boolean | undefined;
}) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)

Executes two effects sequentially, returning the result of the second effect while ignoring the result of the first.

Details

This function allows you to run two effects in sequence, keeping the result of the second effect and discarding the result of the first. By default, the two effects are executed sequentially. If you need them to run concurrently, you can pass the { concurrent: true } option.

The first effect will always be executed, even though its result is ignored. This makes it useful for scenarios where the first effect is needed for its side effects, but only the result of the second effect is important.

When to Use

Use this function when you are only interested in the result of the second effect but still need to run the first effect for its side effects, such as initialization or setup tasks.

Example

import { Effect } from "effect"
const task1 = Effect.succeed(1).pipe(
Effect.delay("200 millis"),
Effect.tap(Effect.log("task1 done"))
)
const task2 = Effect.succeed("hello").pipe(
Effect.delay("100 millis"),
Effect.tap(Effect.log("task2 done"))
)
const program = Effect.zipRight(task1, task2)
Effect.runPromise(program).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="task1 done"
// timestamp=... level=INFO fiber=#0 message="task2 done"
// hello

@seezipLeft for a version that returns the result of the first effect.

@since2.0.0

zipRight
(
import Console
Console
.
const log: (...args: ReadonlyArray<any>) => Effect.Effect<void>

@since2.0.0

log
("done"))
);
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runSync: <void, never>(effect: Effect.Effect<void, never, never>) => void

Executes an effect synchronously, running it immediately and returning the result.

Details

This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling.

Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects.

When to Use

Use this function when:

  • You are sure that the effect will not fail or involve asynchronous operations.
  • You need a direct, synchronous result from the effect.
  • You are working within a context where asynchronous effects are not allowed.

Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using

runPromise

or

runSyncExit

.

Example (Synchronous Logging)

import { Effect } from "effect"
const program = Effect.sync(() => {
console.log("Hello, World!")
return 1
})
const result = Effect.runSync(program)
// Output: Hello, World!
console.log(result)
// Output: 1

Example (Incorrect Usage with Failing or Async Effects)

import { Effect } from "effect"
try {
// Attempt to run an effect that fails
Effect.runSync(Effect.fail("my error"))
} catch (e) {
console.error(e)
}
// Output:
// (FiberFailure) Error: my error
try {
// Attempt to run an effect that involves async work
Effect.runSync(Effect.promise(() => Promise.resolve(1)))
} catch (e) {
console.error(e)
}
// Output:
// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work

@seerunSyncExit for a version that returns an Exit type instead of throwing an error.

@since2.0.0

runSync
(
const program: Effect.Effect<void, never, never>
program
);

This will print messages to a mixture of stdout and stderr.

Terminal window
[stdout] starting
[stdout] trying first password
[stderr] Password must be at least 8 characters
[stdout] trying second password
[stderr] Password must not be a common password
[stdout] trying third password
[stdout] third password OK
[stdout] done

Console.error can be implemented in the same way that was shown in Console.log (44) .