<I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [
never
]
? (input: I) => Result.Result<Unify<A>, R>
: Result.Result<Unify<A>, R>Wraps the match result in a Result, distinguishing matched and unmatched
cases.
Details
This function ensures that the result of a matcher is always wrapped in an
Result, allowing clear differentiation between successful matches
(Ok(value)) and cases where no pattern matched (Err(unmatched
value)).
This approach is particularly useful when handling optional values or when an unmatched case should be explicitly handled rather than returning a default value or throwing an error.
Example (Extracting a user role with Match.result)
import { Match } from "effect"
type User = { readonly role: "admin" | "editor" | "viewer" }
// Create a matcher to extract user roles
const getRole = Match.type<User>().pipe(
Match.when({ role: "admin" }, () => "Has full access"),
Match.when({ role: "editor" }, () => "Can edit content"),
Match.result // Wrap the result in an Result
)
console.log(getRole({ role: "admin" }))
// Output: { _id: 'Result', _tag: 'Ok', ok: 'Has full access' }
console.log(getRole({ role: "viewer" }))
// Output: { _id: 'Result', _tag: 'Err', err: { role: 'viewer' } }export const const result: <I, F, R, A, Pr, Ret>(
self: Matcher<I, F, R, A, Pr, Ret>
) => [Pr] extends [never]
? (input: I) => Result.Result<Unify<A>, R>
: Result.Result<Unify<A>, R>
Wraps the match result in a Result, distinguishing matched and unmatched
cases.
Details
This function ensures that the result of a matcher is always wrapped in an
Result, allowing clear differentiation between successful matches
(Ok(value)) and cases where no pattern matched (Err(unmatched
value)).
This approach is particularly useful when handling optional values or when an
unmatched case should be explicitly handled rather than returning a default
value or throwing an error.
Example (Extracting a user role with Match.result)
import { Match } from "effect"
type User = { readonly role: "admin" | "editor" | "viewer" }
// Create a matcher to extract user roles
const getRole = Match.type<User>().pipe(
Match.when({ role: "admin" }, () => "Has full access"),
Match.when({ role: "editor" }, () => "Can edit content"),
Match.result // Wrap the result in an Result
)
console.log(getRole({ role: "admin" }))
// Output: { _id: 'Result', _tag: 'Ok', ok: 'Has full access' }
console.log(getRole({ role: "viewer" }))
// Output: { _id: 'Result', _tag: 'Err', err: { role: 'viewer' } }
result: <function (type parameter) I in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>I, function (type parameter) F in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>F, function (type parameter) R in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>R, function (type parameter) A in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>A, function (type parameter) Pr in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>Pr, function (type parameter) Ret in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>Ret>(
self: Matcher<I, F, R, A, Pr, Ret>self: type Matcher<
Input,
Filters,
RemainingApplied,
Result,
Provided,
Return = any
> =
| TypeMatcher<
Input,
Filters,
RemainingApplied,
Result,
Return
>
| ValueMatcher<
Input,
Filters,
RemainingApplied,
Result,
Provided,
Return
>
Union type for matchers created by Match.type and Match.value.
Details
A Matcher carries the input type, accumulated filters, remaining cases,
result type, and, for value matchers, the provided value being matched.
Example (Matching string and number values)
import { Match } from "effect"
// Simulated dynamic input that can be a string or a number
const input: string | number = "some input"
// ┌─── string
// ▼
const result = Match.value(input).pipe(
// Match if the value is a number
Match.when(Match.number, (n) => `number: ${n}`),
// Match if the value is a string
Match.when(Match.string, (s) => `string: ${s}`),
// Ensure all possible cases are covered
Match.exhaustive
)
console.log(result)
// Output: "string: some input"
Matcher<function (type parameter) I in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>I, function (type parameter) F in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>F, function (type parameter) R in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>R, function (type parameter) A in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>A, function (type parameter) Pr in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>Pr, function (type parameter) Ret in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>Ret>
) => [function (type parameter) Pr in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>Pr] extends [never] ? (input: Iinput: function (type parameter) I in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>I) => import ResultResult.type Result<A, E = never> = Result.Success<A, E> | Result.Failure<A, E>A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed
/
fail
to construct
- Use
match
to fold both branches
- Use
isSuccess
/
isFailure
to narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)
const failure = Result.fail("something went wrong")
const message = Result.match(success, {
onSuccess: (value) => `Success: ${value}`,
onFailure: (error) => `Error: ${error}`
})
console.log(message)
// Output: "Success: 42"
Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// number
type A = Result.Result.Success<R>
// string
type E = Result.Result.Failure<R>
Result<type Unify<A> = Values<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>> extends infer Z ? Z | FilterInUnmatched<A, Keys<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>>> | FilterOut<A> : never
Unifies types that implement the unification protocol.
When to use
Use to normalize unions of types that expose Effect's unification protocol.
Details
This type performs automatic type unification for types that contain
the unification symbols (unifySymbol, typeSymbol, ignoreSymbol).
It's primarily used internally by the Effect type system to handle
complex type unions and provide better type inference.
Example (Unifying protocol types)
import type { Unify } from "effect"
// Example of types that can be unified
type UnifiableA = {
value: string
[Unify.typeSymbol]?: string
[Unify.unifySymbol]?: { String: () => string }
}
type UnifiableB = {
value: number
[Unify.typeSymbol]?: number
[Unify.unifySymbol]?: { Number: () => number }
}
// Unify automatically handles the union
type Unified = Unify.Unify<UnifiableA | UnifiableB>
// Results in a properly unified type
Unify<function (type parameter) A in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>A>, function (type parameter) R in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>R> : import ResultResult.type Result<A, E = never> = Result.Success<A, E> | Result.Failure<A, E>A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed
/
fail
to construct
- Use
match
to fold both branches
- Use
isSuccess
/
isFailure
to narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)
const failure = Result.fail("something went wrong")
const message = Result.match(success, {
onSuccess: (value) => `Success: ${value}`,
onFailure: (error) => `Error: ${error}`
})
console.log(message)
// Output: "Success: 42"
Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// number
type A = Result.Result.Success<R>
// string
type E = Result.Result.Failure<R>
Result<type Unify<A> = Values<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>> extends infer Z ? Z | FilterInUnmatched<A, Keys<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>>> | FilterOut<A> : never
Unifies types that implement the unification protocol.
When to use
Use to normalize unions of types that expose Effect's unification protocol.
Details
This type performs automatic type unification for types that contain
the unification symbols (unifySymbol, typeSymbol, ignoreSymbol).
It's primarily used internally by the Effect type system to handle
complex type unions and provide better type inference.
Example (Unifying protocol types)
import type { Unify } from "effect"
// Example of types that can be unified
type UnifiableA = {
value: string
[Unify.typeSymbol]?: string
[Unify.unifySymbol]?: { String: () => string }
}
type UnifiableB = {
value: number
[Unify.typeSymbol]?: number
[Unify.unifySymbol]?: { Number: () => number }
}
// Unify automatically handles the union
type Unified = Unify.Unify<UnifiableA | UnifiableB>
// Results in a properly unified type
Unify<function (type parameter) A in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>A>, function (type parameter) R in <I, F, R, A, Pr, Ret>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (input: I) => Result.Result<Unify<A>, R> : Result.Result<Unify<A>, R>R> = import internalinternal.const result: <I, F, R, A, Pr, Ret>(
self: Matcher<I, F, R, A, Pr, Ret>
) => [Pr] extends [never]
? (input: I) => Result.Result<Unify<A>, R>
: Result.Result<Unify<A>, R>
result