#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): numberConverts 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: NumberConstructorAn object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.
Number .NumberConstructor.isNaN(number: unknown): booleanReturns 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): numberConverts 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: NumberConstructorAn object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.
Number .NumberConstructor.isNaN(number: unknown): booleanReturns 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.@exampleimport { 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: PromiseConstructorRepresents 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.@exampleimport { 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: PromiseConstructorRepresents 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.@exampleimport { 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: PromiseConstructorRepresents 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.@exampleimport { 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: PromiseConstructorRepresents 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
| Scenario | Recommended |
|---|---|
| Need all errors for validation | collect |
| Want parallel execution for better performance | collect |
| Operations depend on order (e.g., must stop on first failure) | sequence |
| Want to minimize unnecessary work when failure is likely | sequence |
#References
| Function | Purpose |
|---|---|
| sequence(array) | Stop at the first failure and return it |
| collect(array) | Process all results and gather all errors |
