# Result

`Result<A, E>` represents a computation that either succeeded with a value of
type `A` or failed with an error of type `E`. It is a `Success<A, E>` or a
`Failure<A, E>`. Use it for *synchronous* operations that can fail in a known
way — parsing, validation, decoding — when you want the failure in the return
type rather than as a thrown exception.

In Effect v4, `Result` replaces v3's `Either`. The success type comes **first**
(`Result<A, E>`, mirroring `Effect<A, E, R>`), the constructors are
`Result.succeed` / `Result.fail`, and the payloads are read via `.success` and
`.failure`.

```ts
import { Result } from "effect"

// A synchronous parser that reports failure as a value, not an exception
const parseAge = (input: string): Result.Result<number, string> => {
  const n = Number(input)
  return Number.isInteger(n) && n >= 0
    ? Result.succeed(n)
    : Result.fail(`"${input}" is not a valid age`)
}

const message = Result.match(parseAge("42"), {
  onFailure: (error) => `Invalid: ${error}`,
  onSuccess: (age) => `Parsed age ${age}`
})

console.log(message) // "Parsed age 42"
```

`parseAge` never throws. Its signature, `Result<number, string>`, tells callers
both outcomes are possible, and `Result.match` forces them to handle each.

## Creating a Result

```ts
import { Result } from "effect"

const ok = Result.succeed(42)        // { _id: 'Result', _tag: 'Success', success: 42 }
const err = Result.fail("not found") // { _id: 'Result', _tag: 'Failure', failure: 'not found' }
```

`Result.fromOption` lifts an `Option` into a `Result`, supplying the failure to
use for `None`:

```ts
import { Option, Result } from "effect"

const required = Result.fromOption(
  Option.fromNullishOr(process.env.PORT),
  () => "PORT is not set"
)
```

## Guards

`Result.isSuccess` and `Result.isFailure` narrow the type so you can access the
payload safely:

```ts
import { Result } from "effect"

const result: Result.Result<number, string> = Result.succeed(42)

if (Result.isFailure(result)) {
  console.log(`Failed: ${result.failure}`)
} else {
  console.log(`Succeeded: ${result.success}`)
}
// "Succeeded: 42"
```

## Transforming

`Result.map` transforms a success and passes failures through unchanged;
`Result.mapError` does the opposite. `Result.flatMap` chains a step that itself
returns a `Result`, short-circuiting on the first failure.

```ts
import { Result } from "effect"

const parse = (s: string): Result.Result<number, string> =>
  Number.isNaN(Number(s)) ? Result.fail(`not a number: ${s}`) : Result.succeed(Number(s))

const positive = (n: number): Result.Result<number, string> =>
  n > 0 ? Result.succeed(n) : Result.fail("must be positive")

// Chain two fallible steps; either failure stops the pipeline
const program = parse("10").pipe(
  Result.flatMap(positive),
  Result.map((n) => n * 2)
)

console.log(program) // { _id: 'Result', _tag: 'Success', success: 20 }
```

## Extracting the value

```ts
import { Result } from "effect"

// Supply a default for the failure case
console.log(Result.getOrElse(Result.fail("oops"), (e) => `recovered from ${e}`))
// "recovered from oops"

// Collapse into a single union value
console.log(Result.merge(Result.fail("oops"))) // "oops"

// Throw the raw failure — use only where failure is impossible
console.log(Result.getOrThrow(Result.succeed(1))) // 1
```

## Generator syntax

`Result.gen` reads like `Effect.gen` but short-circuits on the first `Failure`.
Each `yield*` either unwraps a success or aborts the block with that failure.

```ts
import { Result } from "effect"

const parse = (s: string): Result.Result<number, string> =>
  Number.isNaN(Number(s)) ? Result.fail(`not a number: ${s}`) : Result.succeed(Number(s))

const program = Result.gen(function* () {
  const x = yield* parse("10")
  const y = yield* parse("5")
  return x + y
})

console.log(program) // { _id: 'Result', _tag: 'Success', success: 15 }
```

## Interop with Effect

A `Result` can be used directly inside `Effect.gen`: a `Success` yields its
value, a `Failure` fails the effect with `E`. This makes `Result` a natural way
to write synchronous, fallible steps inside an effectful workflow without
juggling two error channels.

```ts
import { Effect, Result } from "effect"

const parse = (s: string): Result.Result<number, string> =>
  Number.isNaN(Number(s)) ? Result.fail(`not a number: ${s}`) : Result.succeed(Number(s))

const program = Effect.gen(function* () {
  // A Failure here propagates as an Effect failure of type string
  const x = yield* parse("10")
  const y = yield* parse("5")
  return x + y
})

Effect.runPromise(program).then(console.log) // 15
```

## Result vs Exit

`Result` is for synchronous, expected failures of type `E`. When you *run* an
effect, the outcome is an [`Exit`](https://effect.plants.sh/data-types/exit-and-cause/), which wraps a
`Cause` rather than a bare `E` — it can also represent defects and
interruptions. Reach for `Result` in pure code, and for `Exit` when inspecting
the result of executing an `Effect`. See
[Result and Exit](https://effect.plants.sh/error-management/result-and-exit/) for how the two relate in
error management.

## API reference

Everything below is a public export of the `Result` module. Each entry has a
short, runnable example with inline `// =>` comments. Most data-last
combinators (`map`, `flatMap`, ...) are `dual`: you can call them
`Result.map(self, f)` or in a pipeline as `self.pipe(Result.map(f))`.

### Constructors

#### succeed

Lifts a value into a successful `Result`. The error type defaults to `never`.

```ts
import { Result } from "effect"

Result.succeed(42)
// => { _id: 'Result', _tag: 'Success', success: 42 }
```

#### fail

Creates a failed `Result`. The success type defaults to `never`.

```ts
import { Result } from "effect"

Result.fail("boom")
// => { _id: 'Result', _tag: 'Failure', failure: 'boom' }
```

#### void

A pre-built `Result<void>` that succeeds with `undefined`. Use when a success
should signal completion without carrying a meaningful value.

```ts
import { Result } from "effect"

const done: Result.Result<void> = Result.void
Result.isSuccess(done)
// => true
```

#### failVoid

A pre-built `Result<never, void>` whose failure value is `undefined`. Use when a
failure is only a control signal and no payload is needed.

```ts
import { Result } from "effect"

Result.failVoid
// => { _id: 'Result', _tag: 'Failure', failure: undefined }
```

#### succeedNone

A pre-built `Result<Option<never>>` that succeeds with `None`. Handy as the
absent branch when working with `transposeOption`.

```ts
import { Result } from "effect"

Result.succeedNone
// => { _id: 'Result', _tag: 'Success', success: { _id: 'Option', _tag: 'None' } }
```

#### succeedSome

Creates a `Result<Option<A>>` that succeeds with `Some(a)`.

```ts
import { Result } from "effect"

Result.succeedSome(42)
// => { _id: 'Result', _tag: 'Success', success: { _id: 'Option', _tag: 'Some', value: 42 } }
```

#### try

Runs a synchronous computation that may throw, capturing the thrown value as a
`Failure`. With a single function the failure type is `unknown`; with
`{ try, catch }` the `catch` function maps the thrown value to `E`.

```ts
import { Result } from "effect"

Result.try(() => JSON.parse('{"ok":true}'))
// => { _id: 'Result', _tag: 'Success', success: { ok: true } }

Result.try({
  try: () => JSON.parse("not json"),
  catch: (e) => `Parse failed: ${e}`
})
// => { _id: 'Result', _tag: 'Failure', failure: 'Parse failed: SyntaxError: ...' }
```

### From other types

#### fromNullishOr

Turns a possibly `null`/`undefined` value into a `Result`. Non-nullish values
become `Success<NonNullable<A>>`; `null`/`undefined` become `Failure<E>` using
the `onNullish` callback (which receives the original value).

```ts
import { Result } from "effect"

Result.fromNullishOr(1, () => "missing")
// => { _id: 'Result', _tag: 'Success', success: 1 }

Result.fromNullishOr(null, () => "missing")
// => { _id: 'Result', _tag: 'Failure', failure: 'missing' }
```

#### fromOption

Converts an `Option<A>` into a `Result<A, E>`. `Some` becomes `Success`; `None`
becomes `Failure`, with the error produced by the `onNone` thunk.

```ts
import { Option, Result } from "effect"

Result.fromOption(Option.some(1), () => "missing")
// => { _id: 'Result', _tag: 'Success', success: 1 }

Result.fromOption(Option.none(), () => "missing")
// => { _id: 'Result', _tag: 'Failure', failure: 'missing' }
```

#### transposeOption

Swaps `Option<Result<A, E>>` into `Result<Option<A>, E>`. `None` becomes
`Success(None)`, `Some(Success(a))` becomes `Success(Some(a))`, and
`Some(Failure(e))` becomes `Failure(e)`.

```ts
import { Option, Result } from "effect"

Result.transposeOption(Option.some(Result.succeed(42)))
// => Success(Some(42))

Result.transposeOption(Option.none<Result.Result<number, string>>())
// => Success(None)

Result.transposeOption(Option.some(Result.fail("err")))
// => { _id: 'Result', _tag: 'Failure', failure: 'err' }
```

#### transposeMapOption

Maps an `Option` value with a `Result`-returning function and transposes in one
step, producing `Result<Option<B>, E>`. `None` short-circuits to
`Success(None)` without calling the function.

```ts
import { Option, Result } from "effect"

const parse = (s: string) =>
  isNaN(Number(s)) ? Result.fail("not a number") : Result.succeed(Number(s))

Result.transposeMapOption(Option.some("42"), parse)
// => Success(Some(42))

Result.transposeMapOption(Option.none(), parse)
// => Success(None)
```

### Guards

#### isResult

Type guard that returns `true` for any `Result` (`Success` or `Failure`),
narrowing unknown input to `Result<unknown, unknown>`.

```ts
import { Result } from "effect"

Result.isResult(Result.succeed(1))
// => true

Result.isResult({ value: 1 })
// => false
```

#### isSuccess

Type guard narrowing a `Result` to `Success<A, E>`, after which `.success` is
accessible.

```ts
import { Result } from "effect"

const r: Result.Result<number, string> = Result.succeed(42)
Result.isSuccess(r) ? r.success : -1
// => 42
```

#### isFailure

Type guard narrowing a `Result` to `Failure<A, E>`, after which `.failure` is
accessible.

```ts
import { Result } from "effect"

const r: Result.Result<number, string> = Result.fail("oops")
Result.isFailure(r) ? r.failure : ""
// => "oops"
```

### Extract payload as Option

#### getSuccess

Extracts the success value as an `Option`, discarding the failure.
`Success<A>` becomes `Some<A>`; `Failure<E>` becomes `None`.

```ts
import { Result } from "effect"

Result.getSuccess(Result.succeed("ok"))
// => { _id: 'Option', _tag: 'Some', value: 'ok' }

Result.getSuccess(Result.fail("err"))
// => { _id: 'Option', _tag: 'None' }
```

#### getFailure

Extracts the failure value as an `Option`, discarding the success.
`Failure<E>` becomes `Some<E>`; `Success<A>` becomes `None`.

```ts
import { Result } from "effect"

Result.getFailure(Result.fail("err"))
// => { _id: 'Option', _tag: 'Some', value: 'err' }

Result.getFailure(Result.succeed("ok"))
// => { _id: 'Option', _tag: 'None' }
```

### Transforming

#### map

Transforms the success value, passing failures through unchanged.

```ts
import { Result } from "effect"

Result.map(Result.succeed(3), (n) => n * 2)
// => { _id: 'Result', _tag: 'Success', success: 6 }

Result.map(Result.fail("err"), (n: number) => n * 2)
// => { _id: 'Result', _tag: 'Failure', failure: 'err' }
```

#### mapError

Transforms the failure value, passing successes through unchanged.

```ts
import { Result } from "effect"

Result.mapError(Result.fail("not found"), (e) => `Error: ${e}`)
// => { _id: 'Result', _tag: 'Failure', failure: 'Error: not found' }
```

#### mapBoth

Transforms both channels at once with `{ onSuccess, onFailure }`, without
changing whether the result succeeds or fails.

```ts
import { Result } from "effect"

Result.mapBoth(Result.succeed(1), {
  onSuccess: (n) => n + 1,
  onFailure: (e: string) => `Error: ${e}`
})
// => { _id: 'Result', _tag: 'Success', success: 2 }
```

#### flatMap

Chains a function returning a `Result` onto a success, merging the error types
into a union. Short-circuits on the first `Failure`. This is the monadic bind.

```ts
import { Result } from "effect"

Result.flatMap(Result.succeed(5), (n) =>
  n > 0 ? Result.succeed(n * 2) : Result.fail("not positive")
)
// => { _id: 'Result', _tag: 'Success', success: 10 }
```

#### andThen

A flexible `flatMap` that also accepts a plain value, a plain-returning
function, or a `Result` directly. If `self` is a `Failure`, the argument is
never evaluated.

```ts
import { Result } from "effect"

Result.andThen(Result.succeed(1), (n) => Result.succeed(n + 1))
// => Success(2)

Result.andThen(Result.succeed(1), (n) => n + 1)
// => Success(2)

Result.andThen(Result.succeed(1), "done")
// => Success("done")
```

#### flip

Swaps the success and failure channels, turning `Result<A, E>` into
`Result<E, A>`.

```ts
import { Result } from "effect"

Result.flip(Result.succeed(42))
// => { _id: 'Result', _tag: 'Failure', failure: 42 }

Result.flip(Result.fail("error"))
// => { _id: 'Result', _tag: 'Success', success: 'error' }
```

#### tap

Runs a side-effect on the success value (e.g. logging) and returns the original
`Result` unchanged. The callback's return value is ignored; it is not called on
a `Failure`.

```ts
import { Result } from "effect"

Result.tap(Result.succeed(42), (n) => console.log("Got:", n))
// logs: "Got: 42"
// => { _id: 'Result', _tag: 'Success', success: 42 }
```

### Filtering / lifting

#### liftPredicate

Builds a `Result` from a raw value guarded by a predicate or refinement. Passing
values become `Success`; failing ones use `orFailWith` to produce the error. A
`Refinement` narrows the success type.

```ts
import { Result } from "effect"

Result.liftPredicate(5, (n: number) => n > 0, (n) => `${n} is not positive`)
// => { _id: 'Result', _tag: 'Success', success: 5 }

Result.liftPredicate(-1, (n: number) => n > 0, (n) => `${n} is not positive`)
// => { _id: 'Result', _tag: 'Failure', failure: '-1 is not positive' }
```

#### filterOrFail

Validates the success value of an existing `Result` with a predicate or
refinement. An existing `Failure` passes through; a passing predicate keeps the
`Success`; a failing one produces a new `Failure` via `orFailWith`. The output
error type is the union of both.

```ts
import { Result } from "effect"

Result.filterOrFail(
  Result.succeed(0),
  (n) => n > 0,
  (n) => `${n} is not positive`
)
// => { _id: 'Result', _tag: 'Failure', failure: '0 is not positive' }
```

### Unwrapping

#### merge

Returns the inner value as `A | E` regardless of the variant — useful when both
channels share a compatible type.

```ts
import { Result } from "effect"

Result.merge(Result.succeed(42))
// => 42

Result.merge(Result.fail("error"))
// => "error"
```

#### getOrElse

Returns the success value, or computes a fallback from the failure value.

```ts
import { Result } from "effect"

Result.getOrElse(Result.succeed(1), () => 0)
// => 1

Result.getOrElse(Result.fail("err"), (e) => `recovered: ${e}`)
// => "recovered: err"
```

#### getOrNull

Returns the success value, or `null` on failure.

```ts
import { Result } from "effect"

Result.getOrNull(Result.succeed(1))
// => 1

Result.getOrNull(Result.fail("err"))
// => null
```

#### getOrUndefined

Returns the success value, or `undefined` on failure.

```ts
import { Result } from "effect"

Result.getOrUndefined(Result.succeed(1))
// => 1

Result.getOrUndefined(Result.fail("err"))
// => undefined
```

#### getOrThrow

Returns the success value, or throws the raw failure value `E`. Use only at
boundaries where failure is unexpected.

```ts
import { Result } from "effect"

Result.getOrThrow(Result.succeed(1))
// => 1

Result.getOrThrow(Result.fail("error"))
// => throws "error"
```

#### getOrThrowWith

Returns the success value, or throws a custom error derived from the failure.

```ts
import { Result } from "effect"

Result.getOrThrowWith(Result.succeed(1), () => new Error("fail"))
// => 1

Result.getOrThrowWith(Result.fail("oops"), (e) => new Error(`Unexpected: ${e}`))
// => throws Error("Unexpected: oops")
```

### Pattern matching

#### match

Folds a `Result` into a single value by applying `onSuccess` or `onFailure`.
Both branches must produce a common type.

```ts
import { Result } from "effect"

const format = Result.match({
  onSuccess: (n: number) => `Got ${n}`,
  onFailure: (e: string) => `Err: ${e}`
})

format(Result.succeed(42))
// => "Got 42"

format(Result.fail("timeout"))
// => "Err: timeout"
```

### Fallbacks

#### orElse

Returns the original `Result` if it is a `Success`; otherwise applies `that` to
the error to produce a recovery `Result`.

```ts
import { Result } from "effect"

Result.orElse(Result.fail("primary failed"), () => Result.succeed(99))
// => { _id: 'Result', _tag: 'Success', success: 99 }

Result.orElse(Result.succeed(1), () => Result.succeed(99))
// => { _id: 'Result', _tag: 'Success', success: 1 }
```

### Combining

#### all

Collects a tuple, struct, or iterable of `Result`s into a single `Result` of
the collected values, preserving structure. **Short-circuits on the first
`Failure`** — later elements are not inspected.

```ts
import { Result } from "effect"

// Tuple
Result.all([Result.succeed(1), Result.succeed("two")])
// => Success([1, "two"])

// Struct
Result.all({ x: Result.succeed(1), y: Result.fail("err") })
// => { _id: 'Result', _tag: 'Failure', failure: 'err' }

// Iterable
Result.all(new Set([Result.succeed(1), Result.succeed(2)]))
// => Success([1, 2])
```

### Equivalence

#### makeEquivalence

Builds an `Equivalence` for `Result` from equivalences for the success and
failure types. Two `Success` values are equal by the success equivalence, two
`Failure` values by the failure equivalence, and a `Success` is never equal to
a `Failure`.

```ts
import { Equivalence, Result } from "effect"

const eq = Result.makeEquivalence(
  Equivalence.strictEqual<number>(),
  Equivalence.strictEqual<string>()
)

eq(Result.succeed(1), Result.succeed(1))
// => true

eq(Result.succeed(1), Result.fail("x"))
// => false
```

### Do-notation & generators

#### gen

Generator-based composition. `yield*` unwraps a `Success` or short-circuits on a
`Failure`; the generator's return value is wrapped in `Success`. Evaluated
eagerly and synchronously.

```ts
import { Result } from "effect"

Result.gen(function* () {
  const a = yield* Result.succeed(1)
  const b = yield* Result.succeed(2)
  return a + b
})
// => { _id: 'Result', _tag: 'Success', success: 3 }
```

#### Do

The starting point for do-notation: a `Result<{}>` (success with an empty
object) to which you add named fields with `bind` and `let`.

```ts
import { pipe, Result } from "effect"

pipe(
  Result.Do,
  Result.bind("x", () => Result.succeed(2)),
  Result.bind("y", () => Result.succeed(3)),
  Result.let("sum", ({ x, y }) => x + y)
)
// => Success({ x: 2, y: 3, sum: 5 })
```

#### bind

Adds a named field to the do-notation accumulator by running a
`Result`-producing function over the current object. Short-circuits on the first
`Failure`.

```ts
import { pipe, Result } from "effect"

pipe(
  Result.Do,
  Result.bind("x", () => Result.succeed(2)),
  Result.bind("y", ({ x }) => Result.succeed(x + 3))
)
// => Success({ x: 2, y: 5 })
```

#### let

Adds a named field to the do-notation accumulator from a pure (non-`Result`)
computation over the current object.

```ts
import { pipe, Result } from "effect"

pipe(
  Result.Do,
  Result.bind("x", () => Result.succeed(2)),
  Result.let("doubled", ({ x }) => x * 2)
)
// => Success({ x: 2, doubled: 4 })
```

#### bindTo

Wraps the success value of an existing `Result` into a named field — typically
to start a do-notation chain from a `Result` you already have.

```ts
import { pipe, Result } from "effect"

pipe(Result.succeed(42), Result.bindTo("answer"))
// => Success({ answer: 42 })
```

## See also

- [Option](https://effect.plants.sh/data-types/option/) — represent optional values; convert with
  `fromOption` / `getSuccess` / `transposeOption`.
- [Exit and Cause](https://effect.plants.sh/data-types/exit-and-cause/) — the outcome of running an
  `Effect`, with a full `Cause` instead of a bare `E`.
- [Result and Exit](https://effect.plants.sh/error-management/result-and-exit/) — using both in error
  management.