The Result primitive
The Rust inspired Result<T, E> primitive in Kōka provides a structured approach for handling both successful values (T) and error cases (E).
This documentation outlines the usage and methods available in the Result class to effectively manage outcomes in your applications.
Usage Consideration
When using the Result<T, E> primitive, it's important to note that it is not intended to be used individually. The entire library is built around its usage under the hood, ensuring consistent and predictable error handling across all functions and methods. Therefore, developers should avoid importing and using the Result primitive in isolation but instead utilize the library's functions that leverage Result internally.
APIs
The Result<T, E> primitive provides several methods to handle and manipulate results, making error management explicit and structured. Below are the APIs offered by the Result<T, E> primitive:
In these APIs' examples we will use the tryAsync utility function that always repond with a Promise of Result.
isOk(): this is Result<T, never>Checks if the result is a value.
Example
const res = await tryAsync(fetch("https://www.some-api.com/api/user"));
if (res.isOk()) {
// handle result value
}isErr(): this is Result<never, E>Checks if the result is an error.
Example
const res = await tryAsync(fetch("https://www.some-api.com/api/user"));
if (res.isErr()) {
// handle result error
}getErr(): this extends Result<never, E> ? E : E | nullReturns the error if the result is an error.
Example
const res = await tryAsync(fetch("https://www.some-api.com/api/user"));
if (res.isErr()) {
const err = res.getErr();
// handle the error
}unwrap(): TUnwraps the result, returning the value if present, or throws the error if not.
Example
const res = await tryAsync(fetch("https://www.some-api.com/api/user"));
if (res.isErr()) {
const err = res.getErr();
// handle the error
} else {
//unwrap the value
const data = res.unwrap();
}unwrapOr(defaultValue: T): TUnwraps the result, returning the value if present, or returns the provided default value.
Example
const user = await tryAsync(fetch("https://www.some-api.com/api/user"));
// if there is an error John Doe is returned instead
return user.unwrapOr("John Doe").name;unwrapUnchecked(): TUnwraps the result, returning the value without checking if an error is present without throwing.
Example
const user = await tryAsync(fetch("https://www.some-api.com/api/user"));
// if there is an error null is returned instead of the user
return user.unwrapUnchecked();map<U>(callback: (value: T) => U): Result<U, E>Transforms the value of the result if it is ok, otherwise returns the error.
Example
const user = await tryAsync(fetch("https://www.some-api.com/api/user"));
const userName = user.map((u) => u.username); //this is still of type Result<T, E>_expect(msg: string): TUnwraps the result, returning the value if present, or throws an error with a custom message.
Some times there is the need to throw, the expect() method allows it.
Example
const user = await tryAsync(fetch("https://www.some-api.com/api/user"));
// if there is an error, throws.
return user._expect("Unable to retrieve user data");Conclusion
The Result<T, E> primitive in Kōka offers a structured approach to manage success and error outcomes. Developers can effectively handle and manipulate results, ensuring clear and predictable error management within their applications.