Skip to content

Either

The Either data type represents two exclusive possible values: an Either<R, L> can be either a Right value or a Left value, where R represents the type of the Right value and L represents the type of the Left value.

  • Either is primarily used as a simple discriminated union and is not recommended as the main result type for operations requiring detailed error information.

  • Exit is the preferred result type within Effect for capturing comprehensive details about failures. It encapsulates the outcomes of effectful computations, distinguishing between success and various failure modes, such as errors, defects and interruptions.

You can create an Either using the Either.right and Either.left constructors.

  • The Either.right function takes a value of type R and constructs a Either<R, never>:

    1
    import {
    import Either
    Either
    } from "effect"
    2
    3
    const
    const rightValue: Either.Either<number, never>
    rightValue
    =
    import Either
    Either
    .
    const right: <number>(right: number) => Either.Either<number, never>

    Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

    right
    (42)
  • The Either.left function takes a value of type L and constructs a Either<never, L>:

    1
    import {
    import Either
    Either
    } from "effect"
    2
    3
    const
    const leftValue: Either.Either<never, string>
    leftValue
    =
    import Either
    Either
    .
    const left: <string>(left: string) => Either.Either<never, string>

    Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

    left
    ("not a number")

You can determine whether an Either is a Left or a Right by using the Either.isLeft and Either.isRight guards:

1
import {
import Either
Either
} from "effect"
2
3
const
const foo: Either.Either<number, never>
foo
=
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(42)
4
5
if (
import Either
Either
.
const isLeft: <number, never>(self: Either.Either<number, never>) => self is Either.Left<never, number>

Determine if a `Either` is a `Left`.

isLeft
(
const foo: Either.Either<number, never>
foo
)) {
6
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(`The left value is: ${
const foo: Either.Left<never, number>
foo
.
(property) Left<never, number>.left: never
left
}`)
7
} else {
8
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(`The Right value is: ${
const foo: Either.Right<never, number>
foo
.
(property) Right<never, number>.right: number
right
}`)
9
}
10
// Output: "The Right value is: 42"

The Either.match function allows you to handle different cases of an Either by providing separate callbacks for each case:

1
import {
import Either
Either
} from "effect"
2
3
const
const foo: Either.Either<number, never>
foo
=
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(42)
4
5
const
const message: string
message
=
import Either
Either
.
const match: <number, never, string, string>(self: Either.Either<number, never>, options: { readonly onLeft: (left: never) => string; readonly onRight: (right: number) => string; }) => string (+1 overload)

Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the `onLeft function, if the value is a `Right` the inner value is applied to the `onRight` function.

match
(
const foo: Either.Either<number, never>
foo
, {
6
(property) onLeft: (left: never) => string
onLeft
: (
(parameter) left: never
left
) => `The left value is: ${
(parameter) left: never
left
}`,
7
(property) onRight: (right: number) => string
onRight
: (
(parameter) right: number
right
) => `The Right value is: ${
(parameter) right: number
right
}`
8
})
9
10
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(
const message: string
message
) // Output: "The Right value is: 42"

Once you have an Either, there are several operations you can perform on it.

You can use the Either.map function to transform the Right value of an Either. The Either.map function takes a transformation function that maps the Right value.

If the Either value is a Left value, the transformation function is ignored, and the Left value is returned unchanged.

Example

1
import {
import Either
Either
} from "effect"
2
3
import Either
Either
.
const map: <number, never, number>(self: Either.Either<number, never>, f: (right: number) => number) => Either.Either<number, never> (+1 overload)

Maps the `Right` side of an `Either` value to a new `Either` value.

map
(
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(1), (
(parameter) n: number
n
) =>
(parameter) n: number
n
+ 1) // right(2)
4
5
import Either
Either
.
const map: <never, string, number>(self: Either.Either<never, string>, f: (right: never) => number) => Either.Either<number, string> (+1 overload)

Maps the `Right` side of an `Either` value to a new `Either` value.

map
(
import Either
Either
.
const left: <string>(left: string) => Either.Either<never, string>

Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

left
("not a number"), (
(parameter) n: never
n
) =>
(parameter) n: never
n
+ 1) // left("not a number")

You can use the Either.mapLeft function to transform the Left value of an Either. The mapLeft function takes a transformation function that maps the Left.

If the Either value is a Right value, the transformation function is ignored, and the Right value is returned unchanged.

Example

1
import {
import Either
Either
} from "effect"
2
3
import Either
Either
.
const mapLeft: <number, never, string>(self: Either.Either<number, never>, f: (left: never) => string) => Either.Either<number, string> (+1 overload)

Maps the `Left` side of an `Either` value to a new `Either` value.

mapLeft
(
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(1), (
(parameter) s: never
s
) =>
(parameter) s: never
s
+ "!") // right(1)
4
5
import Either
Either
.
const mapLeft: <never, string, string>(self: Either.Either<never, string>, f: (left: string) => string) => Either.Either<never, string> (+1 overload)

Maps the `Left` side of an `Either` value to a new `Either` value.

mapLeft
(
import Either
Either
.
const left: <string>(left: string) => Either.Either<never, string>

Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

left
("not a number"), (
(parameter) s: string
s
) =>
(parameter) s: string
s
+ "!") // left("not a number!")

You can use the Either.mapBoth function to transform both the Left and Right values of an Either. The mapBoth function takes two transformation functions: one for the Left value and one for the Right value.

Example

1
import {
import Either
Either
} from "effect"
2
3
import Either
Either
.
const mapBoth: <never, number, string, number>(self: Either.Either<number, never>, options: { readonly onLeft: (left: never) => string; readonly onRight: (right: number) => number; }) => Either.Either<number, string> (+1 overload)
mapBoth
(
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(1), {
4
(property) onLeft: (left: never) => string
onLeft
: (
(parameter) s: never
s
) =>
(parameter) s: never
s
+ "!",
5
(property) onRight: (right: number) => number
onRight
: (
(parameter) n: number
n
) =>
(parameter) n: number
n
+ 1
6
}) // right(2)
7
8
import Either
Either
.
const mapBoth: <string, never, string, number>(self: Either.Either<never, string>, options: { readonly onLeft: (left: string) => string; readonly onRight: (right: never) => number; }) => Either.Either<number, string> (+1 overload)
mapBoth
(
import Either
Either
.
const left: <string>(left: string) => Either.Either<never, string>

Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

left
("not a number"), {
9
(property) onLeft: (left: string) => string
onLeft
: (
(parameter) s: string
s
) =>
(parameter) s: string
s
+ "!",
10
(property) onRight: (right: never) => number
onRight
: (
(parameter) n: never
n
) =>
(parameter) n: never
n
+ 1
11
}) // left("not a number!")

The Either type is a subtype of the Effect type, which means that it can be seamlessly used with functions from the Effect module. These functions are primarily designed to work with Effect values, but they can also handle Either values and process them correctly.

In the context of Effect, the two members of the Either type are treated as follows:

  • Left<L> is equivalent to Effect<never, L>
  • Right<R> is equivalent to Effect<R>

To illustrate this interoperability, let’s consider the following example:

1
import {
import Effect
Effect
,
import Either
Either
} from "effect"
2
3
const
const head: <A>(array: ReadonlyArray<A>) => Either.Either<A, string>
head
= <
(type parameter) A in <A>(array: ReadonlyArray<A>): Either.Either<A, string>
A
>(
(parameter) array: readonly A[]
array
:
interface ReadonlyArray<T>
ReadonlyArray
<
(type parameter) A in <A>(array: ReadonlyArray<A>): Either.Either<A, string>
A
>):
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<
(type parameter) A in <A>(array: ReadonlyArray<A>): Either.Either<A, string>
A
, string> =>
4
(parameter) array: readonly A[]
array
.
(property) ReadonlyArray<A>.length: number

Gets the length of the array. This is a number one higher than the highest element defined in an array.

length
> 0 ?
import Either
Either
.
const right: <A>(right: A) => Either.Either<A, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(
(parameter) array: readonly A[]
array
[0]) :
import Either
Either
.
const left: <string>(left: string) => Either.Either<never, string>

Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

left
("empty array")
5
6
const
const foo: number
foo
=
import Effect
Effect
.
const runSync: <number, string>(effect: Effect.Effect<number, string, never>) => number
runSync
(
7
import Effect
Effect
.
const andThen: <number[], never, never, Either.Either<number, string>>(self: Effect.Effect<number[], never, never>, f: (a: number[]) => Either.Either<number, string>) => Effect.Effect<number, string, never> (+3 overloads)

Executes a sequence of two actions, typically two `Effect`s, where the second action can depend on the result of the first action. The `that` action can take various forms: - a value - a function returning a value - a promise - a function returning a promise - an effect - a function returning an effect

andThen
(
import Effect
Effect
.
const succeed: <number[]>(value: number[]) => Effect.Effect<number[], never, never>
succeed
([1, 2, 3]),
const head: <A>(array: ReadonlyArray<A>) => Either.Either<A, string>
head
)
8
)
9
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(
const foo: number
foo
) // Output: 1
10
11
const
const bar: never
bar
=
import Effect
Effect
.
const runSync: <never, string>(effect: Effect.Effect<never, string, never>) => never
runSync
(
import Effect
Effect
.
const andThen: <never[], never, never, Either.Either<never, string>>(self: Effect.Effect<never[], never, never>, f: (a: never[]) => Either.Either<never, string>) => Effect.Effect<never, string, never> (+3 overloads)

Executes a sequence of two actions, typically two `Effect`s, where the second action can depend on the result of the first action. The `that` action can take various forms: - a value - a function returning a value - a promise - a function returning a promise - an effect - a function returning an effect

andThen
(
import Effect
Effect
.
const succeed: <never[]>(value: never[]) => Effect.Effect<never[], never, never>
succeed
([]),
const head: <A>(array: ReadonlyArray<A>) => Either.Either<A, string>
head
)) // throws "empty array"

The Either.zipWith function allows you to combine two Either values using a provided function. It creates a new Either that holds the combined value of both original Either values.

1
import {
import Either
Either
} from "effect"
2
3
const
const maybeName: Either.Either<string, Error>
maybeName
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<string,
interface Error
Error
> =
import Either
Either
.
const right: <string>(right: string) => Either.Either<string, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
("John")
4
const
const maybeAge: Either.Either<number, Error>
maybeAge
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<number,
interface Error
Error
> =
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(25)
5
6
const
const person: Either.Either<{ name: string; age: number; }, Error>
person
=
import Either
Either
.
const zipWith: <string, Error, number, Error, { name: string; age: number; }>(self: Either.Either<string, Error>, that: Either.Either<number, Error>, f: (right: string, right2: number) => { ...; }) => Either.Either<...> (+1 overload)
zipWith
(
const maybeName: Either.Either<string, Error>
maybeName
,
const maybeAge: Either.Either<number, Error>
maybeAge
, (
(parameter) name: string
name
,
(parameter) age: number
age
) => ({
7
(property) name: string
name
:
(parameter) name: string
name
.
(method) String.toUpperCase(): string

Converts all the alphabetic characters in a string to uppercase.

toUpperCase
(),
8
(property) age: number
age
9
}))
10
11
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(
const person: Either.Either<{ name: string; age: number; }, Error>
person
)
12
/*
13
Output:
14
{ _id: 'Either', _tag: 'Right', right: { name: 'JOHN', age: 25 } }
15
*/

The Either.zipWith function takes three arguments:

  • The first Either you want to combine
  • The second Either you want to combine
  • A function that takes two arguments, which are the values held by the two Either, and returns the combined value

It’s important to note that if either of the two Either values is Left, the resulting Either will also be Left, containing the value of the first encountered Left:

1
import {
import Either
Either
} from "effect"
2
3
const
const maybeName: Either.Either<string, Error>
maybeName
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<string,
interface Error
Error
> =
import Either
Either
.
const right: <string>(right: string) => Either.Either<string, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
("John")
4
const
const maybeAge: Either.Either<number, Error>
maybeAge
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<number,
interface Error
Error
> =
import Either
Either
.
const left: <Error>(left: Error) => Either.Either<never, Error>

Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

left
(
5
new
var Error: ErrorConstructor new (message?: string) => Error
Error
("Oh no!")
6
)
7
8
const
const person: Either.Either<{ name: string; age: number; }, Error>
person
=
import Either
Either
.
const zipWith: <string, Error, number, Error, { name: string; age: number; }>(self: Either.Either<string, Error>, that: Either.Either<number, Error>, f: (right: string, right2: number) => { ...; }) => Either.Either<...> (+1 overload)
zipWith
(
const maybeName: Either.Either<string, Error>
maybeName
,
const maybeAge: Either.Either<number, Error>
maybeAge
, (
(parameter) name: string
name
,
(parameter) age: number
age
) => ({
9
(property) name: string
name
:
(parameter) name: string
name
.
(method) String.toUpperCase(): string

Converts all the alphabetic characters in a string to uppercase.

toUpperCase
(),
10
(property) age: number
age
11
}))
12
13
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(
const person: Either.Either<{ name: string; age: number; }, Error>
person
)
14
/*
15
Output:
16
{ _id: 'Either', _tag: 'Left', left: new Error("Oh no!") }
17
*/

If you need to combine two or more Eithers without transforming the values they hold, you can use Either.all, which takes a collection of Eithers and returns an Either with the same structure.

  • If a tuple is provided, the returned Either will contain a tuple with the same length.
  • If a struct is provided, the returned Either will contain a struct with the same keys.
  • If an iterable is provided, the returned Either will contain an array.
1
import {
import Either
Either
} from "effect"
2
3
const
const maybeName: Either.Either<string, Error>
maybeName
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<string,
interface Error
Error
> =
import Either
Either
.
const right: <string>(right: string) => Either.Either<string, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
("John")
4
const
const maybeAge: Either.Either<number, Error>
maybeAge
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<number,
interface Error
Error
> =
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(25)
5
6
const
const tuple: Either.Either<[string, number], Error>
tuple
=
import Either
Either
.
const all: <readonly [Either.Either<string, Error>, Either.Either<number, Error>]>(input: readonly [Either.Either<string, Error>, Either.Either<number, Error>]) => Either.Either<...>

Takes a structure of `Either`s and returns an `Either` of values with the same structure. - If a tuple is supplied, then the returned `Either` will contain a tuple with the same length. - If a struct is supplied, then the returned `Either` will contain a struct with the same keys. - If an iterable is supplied, then the returned `Either` will contain an array.

all
([
const maybeName: Either.Either<string, Error>
maybeName
,
const maybeAge: Either.Either<number, Error>
maybeAge
])
7
8
const
const struct: Either.Either<{ name: string; age: number; }, Error>
struct
=
import Either
Either
.
const all: <{ readonly name: Either.Either<string, Error>; readonly age: Either.Either<number, Error>; }>(input: { readonly name: Either.Either<string, Error>; readonly age: Either.Either<...>; }) => Either.Either<...>

Takes a structure of `Either`s and returns an `Either` of values with the same structure. - If a tuple is supplied, then the returned `Either` will contain a tuple with the same length. - If a struct is supplied, then the returned `Either` will contain a struct with the same keys. - If an iterable is supplied, then the returned `Either` will contain an array.

all
({
(property) name: Either.Either<string, Error>
name
:
const maybeName: Either.Either<string, Error>
maybeName
,
(property) age: Either.Either<number, Error>
age
:
const maybeAge: Either.Either<number, Error>
maybeAge
})

Note that if one or more Either is a Left, then the first encountered Left will be returned:

1
import { Either } from "effect"
2
3
const maybeName: Either.Either<string, Error> = Either.left(
4
new Error("name not found")
5
)
6
const maybeAge: Either.Either<number, Error> = Either.left(
7
new Error("age not found")
8
)
9
10
const tuple = Either.all([maybeName, maybeAge])
11
12
console.log(tuple)
13
/*
14
Output:
15
{ _id: 'Either', _tag: 'Left', left: new Error("name not found") }
16
*/

Similar to Effect.gen, there’s also Either.gen, which provides a convenient syntax, akin to async/await, for writing code involving Either and using generators.

Let’s revisit the previous example, this time using Either.gen instead of Either.zipWith:

1
import {
import Either
Either
} from "effect"
2
3
const
const maybeName: Either.Either<string, Error>
maybeName
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<string,
interface Error
Error
> =
import Either
Either
.
const right: <string>(right: string) => Either.Either<string, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
("John")
4
const
const maybeAge: Either.Either<number, Error>
maybeAge
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<number,
interface Error
Error
> =
import Either
Either
.
const right: <number>(right: number) => Either.Either<number, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
(25)
5
6
const
const person: Either.Either<{ name: string; age: number; }, Error>
person
=
import Either
Either
.
const gen: Gen <unknown, YieldWrap<Either.Left<Error, string>> | YieldWrap<Either.Right<Error, string>> | YieldWrap<Either.Left<Error, number>> | YieldWrap<...>, { ...; }>(...args: [self: ...] | [body: ...]) => Either.Either<...>
gen
(function* () {
7
const
const name: string
name
= (yield*
const maybeName: Either.Either<string, Error>
maybeName
).
(method) String.toUpperCase(): string

Converts all the alphabetic characters in a string to uppercase.

toUpperCase
()
8
const
const age: number
age
= yield*
const maybeAge: Either.Either<number, Error>
maybeAge
9
return {
(property) name: string
name
,
(property) age: number
age
}
10
})
11
12
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(
const person: Either.Either<{ name: string; age: number; }, Error>
person
)
13
/*
14
Output:
15
{ _id: 'Either', _tag: 'Right', right: { name: 'JOHN', age: 25 } }
16
*/

Once again, if either of the two Either values is Left, the resulting Either will also be Left:

1
import {
import Either
Either
} from "effect"
2
3
const
const maybeName: Either.Either<string, Error>
maybeName
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<string,
interface Error
Error
> =
import Either
Either
.
const right: <string>(right: string) => Either.Either<string, never>

Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias of this structure.

right
("John")
4
const
const maybeAge: Either.Either<number, Error>
maybeAge
:
import Either
Either
.
type Either<R, L = never> = Either.Left<L, R> | Either.Right<L, R> namespace Either
Either
<number,
interface Error
Error
> =
import Either
Either
.
const left: <Error>(left: Error) => Either.Either<never, Error>

Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this structure.

left
(
5
new
var Error: ErrorConstructor new (message?: string) => Error
Error
("Oh no!")
6
)
7
8
const
const person: Either.Either<{ name: string; age: number; }, Error>
person
=
import Either
Either
.
const gen: Gen <unknown, YieldWrap<Either.Left<Error, string>> | YieldWrap<Either.Right<Error, string>> | YieldWrap<Either.Left<Error, number>> | YieldWrap<...>, { ...; }>(...args: [self: ...] | [body: ...]) => Either.Either<...>
gen
(function* () {
9
const
const name: string
name
= (yield*
const maybeName: Either.Either<string, Error>
maybeName
).
(method) String.toUpperCase(): string

Converts all the alphabetic characters in a string to uppercase.

toUpperCase
()
10
const
const age: number
age
= yield*
const maybeAge: Either.Either<number, Error>
maybeAge
11
return {
(property) name: string
name
,
(property) age: number
age
}
12
})
13
14
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

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

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(
const person: Either.Either<{ name: string; age: number; }, Error>
person
)
15
/*
16
Output:
17
{ _id: 'Either', _tag: 'Left', left: new Error("Oh no!") }
18
*/