• English
  • Aggregating Results

    When you have multiple Results that need to be combined, sequence and collect are your go-to functions. They both aggregate Results, but differ in how they handle failures.

    sequence - Stop at First Failure

    sequence processes Results and stops at the first failure:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    // All succeed const
    const success: Result.Result<[1, 2, 3], never>
    success
    =
    import Result
    Result
    .
    const sequence: <[Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]>(x: [Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]) => Result.Result<[1, 2, 3], never> (+4 overloads)
    sequence
    ([
    import Result
    Result
    .
    const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
    succeed
    (1),
    import Result
    Result
    .
    const succeed: <2>(value: 2) => Result.Result<2, never> (+1 overload)
    succeed
    (2),
    import Result
    Result
    .
    const succeed: <3>(value: 3) => Result.Result<3, never> (+1 overload)
    succeed
    (3),
    ]); // { type: 'Success', value: [1, 2, 3] } // One fails - stops immediately const
    const failure: Result.Result<[1, never, 3], "error">
    failure
    =
    import Result
    Result
    .
    const sequence: <[Result.Result<1, never>, Result.Result<never, "error">, Result.Result<3, never>]>(x: [Result.Result<1, never>, Result.Result<never, "error">, Result.Result<3, never>]) => Result.Result<[1, never, 3], "error"> (+4 overloads)
    sequence
    ([
    import Result
    Result
    .
    const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
    succeed
    (1),
    import Result
    Result
    .
    const fail: <"error">(error: "error") => Result.Result<never, "error"> (+1 overload)
    fail
    ('error'),
    import Result
    Result
    .
    const succeed: <3>(value: 3) => Result.Result<3, never> (+1 overload)
    succeed
    (3), // Never evaluated in lazy mode
    ]); // { type: 'Failure', error: 'error' }

    With Objects

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    // All succeed const
    const success: Result.Result<{
        name: "Alice";
        age: 30;
        email: "alice@example.com";
    }, never>
    success
    =
    import Result
    Result
    .
    const sequence: <{
        name: Result.Result<"Alice", never>;
        age: Result.Result<30, never>;
        email: Result.Result<"alice@example.com", never>;
    }>(x: {
        name: Result.Result<"Alice", never>;
        age: Result.Result<30, never>;
        email: Result.Result<"alice@example.com", never>;
    }) => Result.Result<{
        name: "Alice";
        age: 30;
        email: "alice@example.com";
    }, never> (+4 overloads)
    sequence
    ({
    name: Result.Result<"Alice", never>
    name
    :
    import Result
    Result
    .
    const succeed: <"Alice">(value: "Alice") => Result.Result<"Alice", never> (+1 overload)
    succeed
    ('Alice'),
    age: Result.Result<30, never>
    age
    :
    import Result
    Result
    .
    const succeed: <30>(value: 30) => Result.Result<30, never> (+1 overload)
    succeed
    (30),
    email: Result.Result<"alice@example.com", never>
    email
    :
    import Result
    Result
    .
    const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
    succeed
    ('alice@example.com'),
    }); // { type: 'Success', value: { name: 'Alice', age: 30, email: 'alice@example.com' } } // One fails - stops immediately const
    const result: Result.Result<{
        name: "Alice";
        age: never;
        email: "alice@example.com";
    }, "error">
    result
    =
    import Result
    Result
    .
    const sequence: <{
        name: Result.Result<"Alice", never>;
        age: Result.Result<never, "error">;
        email: Result.Result<"alice@example.com", never>;
    }>(x: {
        name: Result.Result<"Alice", never>;
        age: Result.Result<never, "error">;
        email: Result.Result<"alice@example.com", never>;
    }) => Result.Result<{
        name: "Alice";
        age: never;
        email: "alice@example.com";
    }, "error"> (+4 overloads)
    sequence
    ({
    name: Result.Result<"Alice", never>
    name
    :
    import Result
    Result
    .
    const succeed: <"Alice">(value: "Alice") => Result.Result<"Alice", never> (+1 overload)
    succeed
    ('Alice'),
    age: Result.Result<never, "error">
    age
    :
    import Result
    Result
    .
    const fail: <"error">(error: "error") => Result.Result<never, "error"> (+1 overload)
    fail
    ('error'),
    email: Result.Result<"alice@example.com", never>
    email
    :
    import Result
    Result
    .
    const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
    succeed
    ('alice@example.com'), // Never evaluated in lazy mode
    }); // { type: 'Failure', error: 'error' }

    Example: Purchase Processing Pipeline

    A common use case is a purchase flow where multiple independent operations must all succeed. With sequence, if any step fails, the remaining operations are skipped:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const processPurchase: (user: User, product: Product) => Result.ResultAsync<{
        stock: Stock;
        order: Order;
        confirmation: Confirmation;
    }, "OutOfStock" | "OrderFailed" | "EmailFailed">
    processPurchase
    = (
    user: User
    user
    :
    type User = {
        id: string;
        email: string;
    }
    User
    ,
    product: Product
    product
    :
    type Product = {
        id: string;
        name: string;
    }
    Product
    ) => {
    return
    import Result
    Result
    .
    const sequence: <{
        stock: Result.ResultAsync<Stock, "OutOfStock">;
        order: Result.ResultAsync<Order, "OrderFailed">;
        confirmation: Result.ResultAsync<Confirmation, "EmailFailed">;
    }>(x: {
        stock: Result.ResultAsync<Stock, "OutOfStock">;
        order: Result.ResultAsync<Order, "OrderFailed">;
        confirmation: Result.ResultAsync<Confirmation, "EmailFailed">;
    }) => Result.ResultAsync<{
        stock: Stock;
        order: Order;
        confirmation: Confirmation;
    }, "OutOfStock" | "OrderFailed" | "EmailFailed"> (+4 overloads)
    sequence
    ({
    stock: Result.ResultAsync<Stock, "OutOfStock">
    stock
    :
    const reserveStock: (product: Product) => Result.ResultAsync<Stock, "OutOfStock">
    reserveStock
    (
    product: Product
    product
    ),
    order: Result.ResultAsync<Order, "OrderFailed">
    order
    :
    const createOrder: (user: User, product: Product) => Result.ResultAsync<Order, "OrderFailed">
    createOrder
    (
    user: User
    user
    ,
    product: Product
    product
    ),
    confirmation: Result.ResultAsync<Confirmation, "EmailFailed">
    confirmation
    :
    const sendConfirmationEmail: (user: User, product: Product) => Result.ResultAsync<Confirmation, "EmailFailed">
    sendConfirmationEmail
    (
    user: User
    user
    ,
    product: Product
    product
    )
    }); }; // All succeed: await
    const processPurchase: (user: User, product: Product) => Result.ResultAsync<{
        stock: Stock;
        order: Order;
        confirmation: Confirmation;
    }, "OutOfStock" | "OrderFailed" | "EmailFailed">
    processPurchase
    (
    const user: User
    user
    ,
    const book: Product
    book
    );
    // { type: 'Success', value: { stock: {...}, order: {...}, confirmation: {...} } } // If reserveStock fails → stops immediately, order and email are not processed await
    const processPurchase: (user: User, product: Product) => Result.ResultAsync<{
        stock: Stock;
        order: Order;
        confirmation: Confirmation;
    }, "OutOfStock" | "OrderFailed" | "EmailFailed">
    processPurchase
    (
    const user: User
    user
    ,
    const gadget: Product
    gadget
    );
    // { type: 'Failure', error: 'OutOfStock' }

    collect - Gather All Errors

    collect processes all Results and gathers all errors:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    // All succeed const
    const success: Result.Result<[1, 2, 3], never[]>
    success
    =
    import Result
    Result
    .
    const collect: <[Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]>(x: [Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]) => Result.Result<[1, 2, 3], never[]> (+4 overloads)
    collect
    ([
    import Result
    Result
    .
    const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
    succeed
    (1),
    import Result
    Result
    .
    const succeed: <2>(value: 2) => Result.Result<2, never> (+1 overload)
    succeed
    (2),
    import Result
    Result
    .
    const succeed: <3>(value: 3) => Result.Result<3, never> (+1 overload)
    succeed
    (3),
    ]); // { type: 'Success', value: [1, 2, 3] } // Multiple failures - collects all errors const
    const failure: Result.Result<[1, never, never], ("error1" | "error2")[]>
    failure
    =
    import Result
    Result
    .
    const collect: <[Result.Result<1, never>, Result.Result<never, "error1">, Result.Result<never, "error2">]>(x: [Result.Result<1, never>, Result.Result<never, "error1">, Result.Result<never, "error2">]) => Result.Result<[1, never, never], ("error1" | "error2")[]> (+4 overloads)
    collect
    ([
    import Result
    Result
    .
    const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
    succeed
    (1),
    import Result
    Result
    .
    const fail: <"error1">(error: "error1") => Result.Result<never, "error1"> (+1 overload)
    fail
    ('error1'),
    import Result
    Result
    .
    const fail: <"error2">(error: "error2") => Result.Result<never, "error2"> (+1 overload)
    fail
    ('error2'),
    ]); // { type: 'Failure', error: ['error1', 'error2'] }

    With Objects

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    // All succeed const
    const success: Result.Result<{
        name: "Alice";
        age: 30;
        email: "alice@example.com";
    }, never[]>
    success
    =
    import Result
    Result
    .
    const collect: <{
        name: Result.Result<"Alice", never>;
        age: Result.Result<30, never>;
        email: Result.Result<"alice@example.com", never>;
    }>(x: {
        name: Result.Result<"Alice", never>;
        age: Result.Result<30, never>;
        email: Result.Result<"alice@example.com", never>;
    }) => Result.Result<{
        name: "Alice";
        age: 30;
        email: "alice@example.com";
    }, never[]> (+4 overloads)
    collect
    ({
    name: Result.Result<"Alice", never>
    name
    :
    import Result
    Result
    .
    const succeed: <"Alice">(value: "Alice") => Result.Result<"Alice", never> (+1 overload)
    succeed
    ('Alice'),
    age: Result.Result<30, never>
    age
    :
    import Result
    Result
    .
    const succeed: <30>(value: 30) => Result.Result<30, never> (+1 overload)
    succeed
    (30),
    email: Result.Result<"alice@example.com", never>
    email
    :
    import Result
    Result
    .
    const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
    succeed
    ('alice@example.com'),
    }); // { type: 'Success', value: { name: 'Alice', age: 30, email: 'alice@example.com' } } // Multiple failures - collects all errors const
    const result: Result.Result<{
        name: never;
        age: never;
        email: "alice@example.com";
    }, ("Name is required" | "Invalid age")[]>
    result
    =
    import Result
    Result
    .
    const collect: <{
        name: Result.Result<never, "Name is required">;
        age: Result.Result<never, "Invalid age">;
        email: Result.Result<"alice@example.com", never>;
    }>(x: {
        name: Result.Result<never, "Name is required">;
        age: Result.Result<never, "Invalid age">;
        email: Result.Result<"alice@example.com", never>;
    }) => Result.Result<{
        name: never;
        age: never;
        email: "alice@example.com";
    }, ("Name is required" | "Invalid age")[]> (+4 overloads)
    collect
    ({
    name: Result.Result<never, "Name is required">
    name
    :
    import Result
    Result
    .
    const fail: <"Name is required">(error: "Name is required") => Result.Result<never, "Name is required"> (+1 overload)
    fail
    ('Name is required'),
    age: Result.Result<never, "Invalid age">
    age
    :
    import Result
    Result
    .
    const fail: <"Invalid age">(error: "Invalid age") => Result.Result<never, "Invalid age"> (+1 overload)
    fail
    ('Invalid age'),
    email: Result.Result<"alice@example.com", never>
    email
    :
    import Result
    Result
    .
    const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
    succeed
    ('alice@example.com'),
    }); // { type: 'Failure', error: ['Name is required', 'Invalid age'] }

    Example: Parallel API Data Aggregation

    A common use case is fetching data from multiple independent APIs. With collect, all API calls are made in parallel, and if multiple services fail, all errors are reported together:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const fetchUserDashboard: (userId: string) => Promise<Result.Result<{
        user: User;
        orders: Orders;
        reviews: Reviews;
    }, FetchError[]>>
    fetchUserDashboard
    = async (
    userId: string
    userId
    : string) => {
    // All three API calls execute in parallel return
    import Result
    Result
    .
    const collect: <{
        user: Result.ResultAsync<User, FetchError>;
        orders: Result.ResultAsync<Orders, FetchError>;
        reviews: Result.ResultAsync<Reviews, FetchError>;
    }>(x: {
        user: Result.ResultAsync<User, FetchError>;
        orders: Result.ResultAsync<Orders, FetchError>;
        reviews: Result.ResultAsync<Reviews, FetchError>;
    }) => Result.ResultAsync<{
        user: User;
        orders: Orders;
        reviews: Reviews;
    }, FetchError[]> (+4 overloads)
    collect
    ({
    user: Result.ResultAsync<User, FetchError>
    user
    :
    const fetchUser: (id: string) => Result.ResultAsync<User, FetchError>
    fetchUser
    (
    userId: string
    userId
    ),
    orders: Result.ResultAsync<Orders, FetchError>
    orders
    :
    const fetchOrders: (userId: string) => Result.ResultAsync<Orders, FetchError>
    fetchOrders
    (
    userId: string
    userId
    ),
    reviews: Result.ResultAsync<Reviews, FetchError>
    reviews
    :
    const fetchReviews: (userId: string) => Result.ResultAsync<Reviews, FetchError>
    fetchReviews
    (
    userId: string
    userId
    ),
    }); }; // All APIs succeed: await
    const fetchUserDashboard: (userId: string) => Promise<Result.Result<{
        user: User;
        orders: Orders;
        reviews: Reviews;
    }, FetchError[]>>
    fetchUserDashboard
    ('user-123');
    // { // type: 'Success', // value: { // user: { id: 'user-123', name: 'Alice' }, // orders: [{ id: 'order-123', name: 'Product A' }], // reviews: [{ id: 'review-123', comment: 'Great!' }] // }, // } // Multiple APIs fail - all errors are collected: await
    const fetchUserDashboard: (userId: string) => Promise<Result.Result<{
        user: User;
        orders: Orders;
        reviews: Reviews;
    }, FetchError[]>>
    fetchUserDashboard
    ('invalid-user');
    // { // type: 'Failure', // error: [ // 'User not found', // 'Orders fetch failed', // ], // }

    Since collect executes async operations in parallel, all API calls start simultaneously—improving performance compared to sequential execution. Additionally, if multiple services fail, all errors are reported together, making debugging easier.

    Using with Mapper Functions

    Both functions accept a mapper function to transform values into Results:

    sequence with Mapper

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const parseNumbers: (strings: string[]) => Result.Result<number[], `Invalid number: ${string}`>
    parseNumbers
    = (
    strings: string[]
    strings
    : string[]) => {
    return
    import Result
    Result
    .
    const sequence: <string[], (str: string) => Result.Failure<`Invalid number: ${string}`> | Result.Success<number>>(x: string[], fn: (str: string) => Result.Failure<`Invalid number: ${string}`> | Result.Success<number>) => Result.Result<number[], `Invalid number: ${string}`> (+4 overloads)
    sequence
    (
    strings: string[]
    strings
    , (
    str: string
    str
    ) => {
    const
    const num: number
    num
    =
    function parseInt(string: string, radix?: number): number

    Converts a string to an integer.

    @paramstring A string to convert into a number.@paramradix A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
    parseInt
    (
    str: string
    str
    , 10);
    if (
    var Number: NumberConstructor

    An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

    Number
    .
    NumberConstructor.isNaN(number: unknown): boolean

    Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter to a number. Only values of the type number, that are also NaN, result in true.

    @paramnumber A numeric value.
    isNaN
    (
    const num: number
    num
    )) {
    return
    import Result
    Result
    .
    const fail: <`Invalid number: ${string}`>(error: `Invalid number: ${string}`) => Result.Result<never, `Invalid number: ${string}`> (+1 overload)
    fail
    (`Invalid number: ${
    str: string
    str
    }`);
    } return
    import Result
    Result
    .
    const succeed: <number>(value: number) => Result.Result<number, never> (+1 overload)
    succeed
    (
    const num: number
    num
    );
    }); };
    const parseNumbers: (strings: string[]) => Result.Result<number[], `Invalid number: ${string}`>
    parseNumbers
    (['1', '2', '3']);
    // { type: 'Success', value: [1, 2, 3] }
    const parseNumbers: (strings: string[]) => Result.Result<number[], `Invalid number: ${string}`>
    parseNumbers
    (['1', 'abc', 'xyz']);
    // { type: 'Failure', error: 'Invalid number: abc' }

    collect with Mapper

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const parseNumbers: (strings: string[]) => Result.Result<number[], `Invalid number: ${string}`[]>
    parseNumbers
    = (
    strings: string[]
    strings
    : string[]) => {
    return
    import Result
    Result
    .
    const collect: <string[], (str: string) => Result.Failure<`Invalid number: ${string}`> | Result.Success<number>>(x: string[], fn: (str: string) => Result.Failure<`Invalid number: ${string}`> | Result.Success<number>) => Result.Result<number[], `Invalid number: ${string}`[]> (+4 overloads)
    collect
    (
    strings: string[]
    strings
    , (
    str: string
    str
    ) => {
    const
    const num: number
    num
    =
    function parseInt(string: string, radix?: number): number

    Converts a string to an integer.

    @paramstring A string to convert into a number.@paramradix A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
    parseInt
    (
    str: string
    str
    , 10);
    if (
    var Number: NumberConstructor

    An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

    Number
    .
    NumberConstructor.isNaN(number: unknown): boolean

    Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter to a number. Only values of the type number, that are also NaN, result in true.

    @paramnumber A numeric value.
    isNaN
    (
    const num: number
    num
    )) {
    return
    import Result
    Result
    .
    const fail: <`Invalid number: ${string}`>(error: `Invalid number: ${string}`) => Result.Result<never, `Invalid number: ${string}`> (+1 overload)
    fail
    (`Invalid number: ${
    str: string
    str
    }`);
    } return
    import Result
    Result
    .
    const succeed: <number>(value: number) => Result.Result<number, never> (+1 overload)
    succeed
    (
    const num: number
    num
    );
    }); };
    const parseNumbers: (strings: string[]) => Result.Result<number[], `Invalid number: ${string}`[]>
    parseNumbers
    (['1', '2', '3']);
    // { type: 'Success', value: [1, 2, 3] }
    const parseNumbers: (strings: string[]) => Result.Result<number[], `Invalid number: ${string}`[]>
    parseNumbers
    (['1', 'abc', 'xyz']);
    // { type: 'Failure', error: ['Invalid number: abc', 'Invalid number: xyz'] }

    Async Behavior

    When working with ResultAsync (asynchronous Results), sequence and collect behave differently:

    sequence - Sequential Execution

    sequence executes async operations sequentially (one after another). Each Result is awaited before processing the next one, and execution stops immediately upon encountering a failure:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const fetchUser: (id: string) => Result.ResultAsync<string, string>
    fetchUser
    = (
    id: string
    id
    : string):
    import Result
    Result
    .
    type ResultAsync<T, E> = Promise<Result.Result<T, E>>

    An asynchronous variant of Result , wrapped in a Promise.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const fetchData = async (): Result.ResultAsync<string, Error> => {
      try {
        const data = await fetch('...');
        return { type: 'Success', value: await data.text() };
      } catch (err) {
        return { type: 'Failure', error: err as Error };
      }
    };
    @categoryCore Types
    ResultAsync
    <string, string> =>
    import Result
    Result
    .
    const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
    succeed
    (
    var Promise: PromiseConstructor

    Represents the completion of an asynchronous operation

    Promise
    .
    PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

    Creates a new resolved promise for the provided value.

    @paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
    resolve
    (`User ${
    id: string
    id
    }`));
    const
    const fetchOrder: (id: string) => Result.ResultAsync<string, string>
    fetchOrder
    = (
    id: string
    id
    : string):
    import Result
    Result
    .
    type ResultAsync<T, E> = Promise<Result.Result<T, E>>

    An asynchronous variant of Result , wrapped in a Promise.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const fetchData = async (): Result.ResultAsync<string, Error> => {
      try {
        const data = await fetch('...');
        return { type: 'Success', value: await data.text() };
      } catch (err) {
        return { type: 'Failure', error: err as Error };
      }
    };
    @categoryCore Types
    ResultAsync
    <string, string> =>
    import Result
    Result
    .
    const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
    succeed
    (
    var Promise: PromiseConstructor

    Represents the completion of an asynchronous operation

    Promise
    .
    PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

    Creates a new resolved promise for the provided value.

    @paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
    resolve
    (`Order ${
    id: string
    id
    }`));
    // Operations are executed sequentially: fetchUser completes, then fetchOrder starts const
    const result: Result.Result<{
        user: string;
        order: string;
    }, string>
    result
    = await
    import Result
    Result
    .
    const sequence: <{
        user: Result.ResultAsync<string, string>;
        order: Result.ResultAsync<string, string>;
    }>(x: {
        user: Result.ResultAsync<string, string>;
        order: Result.ResultAsync<string, string>;
    }) => Result.ResultAsync<{
        user: string;
        order: string;
    }, string> (+4 overloads)
    sequence
    ({
    user: Result.ResultAsync<string, string>
    user
    :
    const fetchUser: (id: string) => Result.ResultAsync<string, string>
    fetchUser
    ('1'),
    order: Result.ResultAsync<string, string>
    order
    :
    const fetchOrder: (id: string) => Result.ResultAsync<string, string>
    fetchOrder
    ('100'),
    }); // { type: 'Success', value: { user: 'User 1', order: 'Order 100' } }

    collect - Parallel Execution

    collect executes async operations in parallel using Promise.all(). All operations start simultaneously and all results are awaited together:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const fetchUser: (id: string) => Result.ResultAsync<string, string>
    fetchUser
    = (
    id: string
    id
    : string):
    import Result
    Result
    .
    type ResultAsync<T, E> = Promise<Result.Result<T, E>>

    An asynchronous variant of Result , wrapped in a Promise.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const fetchData = async (): Result.ResultAsync<string, Error> => {
      try {
        const data = await fetch('...');
        return { type: 'Success', value: await data.text() };
      } catch (err) {
        return { type: 'Failure', error: err as Error };
      }
    };
    @categoryCore Types
    ResultAsync
    <string, string> =>
    import Result
    Result
    .
    const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
    succeed
    (
    var Promise: PromiseConstructor

    Represents the completion of an asynchronous operation

    Promise
    .
    PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

    Creates a new resolved promise for the provided value.

    @paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
    resolve
    (`User ${
    id: string
    id
    }`));
    const
    const fetchOrder: (id: string) => Result.ResultAsync<string, string>
    fetchOrder
    = (
    id: string
    id
    : string):
    import Result
    Result
    .
    type ResultAsync<T, E> = Promise<Result.Result<T, E>>

    An asynchronous variant of Result , wrapped in a Promise.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const fetchData = async (): Result.ResultAsync<string, Error> => {
      try {
        const data = await fetch('...');
        return { type: 'Success', value: await data.text() };
      } catch (err) {
        return { type: 'Failure', error: err as Error };
      }
    };
    @categoryCore Types
    ResultAsync
    <string, string> =>
    import Result
    Result
    .
    const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
    succeed
    (
    var Promise: PromiseConstructor

    Represents the completion of an asynchronous operation

    Promise
    .
    PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

    Creates a new resolved promise for the provided value.

    @paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
    resolve
    (`Order ${
    id: string
    id
    }`));
    // Operations are executed in parallel: both start at the same time const
    const result: Result.Result<{
        user: string;
        order: string;
    }, string[]>
    result
    = await
    import Result
    Result
    .
    const collect: <{
        user: Result.ResultAsync<string, string>;
        order: Result.ResultAsync<string, string>;
    }>(x: {
        user: Result.ResultAsync<string, string>;
        order: Result.ResultAsync<string, string>;
    }) => Result.ResultAsync<{
        user: string;
        order: string;
    }, string[]> (+4 overloads)
    collect
    ({
    user: Result.ResultAsync<string, string>
    user
    :
    const fetchUser: (id: string) => Result.ResultAsync<string, string>
    fetchUser
    ('1'),
    order: Result.ResultAsync<string, string>
    order
    :
    const fetchOrder: (id: string) => Result.ResultAsync<string, string>
    fetchOrder
    ('100'),
    }); // { type: 'Success', value: { user: 'User 1', order: 'Order 100' } }

    Choosing Between sequence and collect

    ScenarioRecommended
    Need all errors for validationcollect
    Want parallel execution for better performancecollect
    Operations depend on order (e.g., must stop on first failure)sequence
    Want to minimize unnecessary work when failure is likelysequence

    References

    FunctionPurpose
    sequence(array)Stop at the first failure and return it
    collect(array)Process all results and gather all errors