Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Result type

From Wikipedia, the free encyclopedia

In functional programming, a result type is a monadic type holding a returned value or an error code. They provide an elegant way of handling errors, without resorting to exception handling; when a function that may fail returns a result type, the programmer is forced to consider success or failure paths, before getting access to the expected result; this eliminates the possibility of an erroneous programmer assumption.

Examples

[edit]
  • In C++, it is defined by the standard library as std::expected<T, E>.[1]
  • In Elm, it is defined by the standard library as type Result e v = Ok v | Err e.[2]
  • In Haskell, by convention the Either type is used for this purpose, which is defined by the standard library as data Either a b = Left a | Right b, where a is the error type and b is the return type.[3]
  • In Java, it is not natively in the standard library, but is available from third party libraries. For example, result4j which includes an interface com.github.sviperll.result4j.Result<R, E> similar to Rust Result<T, E>, and vavr includes an interface io.vavr.control.Either<L, R> similar to Haskell Either a b. Because Java and Kotlin are cross-compatible, Java can use the kotlin.Result<T> type from Kotlin.
  • In Kotlin, it is defined by the standard library as kotlin.Result<T>.[4]
  • In OCaml, it is defined by the standard library as type ('a, 'b) result = Ok of 'a | Error of 'b type.[5]
  • In Python, it is not natively in the standard library, but is available from third party libraries such as returns and result.
  • In Rust, it is defined by the standard library as std::result::Result<T, E>, an enum with Ok and Err cases.[6][7] Additional aliases inside other namespaces exist, such as std::io::Result<T> (which is an alias for std::result::Result<T, std::io::Error>).
  • In Scala, the standard library also defines an Either type,[8] however Scala also has more conventional exception handling.
  • In Swift, it is defined by the standard library as @frozen enum Result<Success, Failure> where Failure : Error.[9]
  • In V, the result type is implemented natively using !T as the return type of a function. For example fn my_function() !string { ... }. Error Handling in V.

C++

[edit]

The std::expected<T, E> class uses std::unexpected() to return the type E, and can return T directly.

import std;

using std::expected;
using std::ifstream;
using std::string;
using std::stringstream;
using std::unexpected;
using std::filesystem::path;

enum class FileError {
    MISSING_FILE,
    NO_PERMISSION,
    // more errors here
};

expected<string, FileError> loadConfig(const path& p) noexcept {
    if (!std::filesystem::exists(p)) {
        return unexpected(FileError::MISSING_FILE);
    }
    ifstream config{p};
    stringstream buffer;
    if (!config.is_open()) {
        return unexpected(FileError::NO_PERMISSION);
    }
    buffer << config.rdbuf();
    config.close();
    return buffer.str();
}

int main(int argc, char* argv[]) {
    path p{"configs/my_config.txt"};
    if (const expected<String, FileError> s = loadConfig(p); s.has_value()) {
        std::println("Config contents: {}", s.value());
    } else {
        switch (s.error) {
            case FileError::MISSING_FILE:
                std::println("Error: path {} not valid or missing!", p);
                break;
            case FileError::NO_PERMISSION:
                std::println("Error: no permission to read file at path {}!", p);
                break;
            // additional cases...
            default:
                std::unreachable();
        }
    }
}

A tag std::unexpect (of type std::unexpect_t) may be used to directly construct an error state inside a std::expected.[10] A specialization for std::expected<void, E> exists for when a function does not return any data upon success. If the value() method is called on a std::expected that contains an error, a std::bad_expected_access exception is thrown.[11]

Rust

[edit]

Enums in Rust are tagged unions, which can be unpacked with strong type checking through pattern matching. The Rust expected type is std::result::Result<T, E>, with additional aliases across the standard library.

const CAT_FOUND: bool = true;

fn main() {
    let result: Result<(), String> = pet_cat();
    match result {
        Ok(_) => println!("Great, we could pet the cat!"),
        Err(error) => println!("Oh no, we couldn't pet the cat: {error}")
    }
}

fn pet_cat() -> Result<(), String> {
    if CAT_FOUND {
        Ok(())
    } else {
        Err(String::from("The cat is nowhere to be found!"))
    }
}

Vlang

[edit]

The Error type is an interface for iError.

const cat_found = true

fn main() {
    cat_name := get_pet_cat_name() or { 
        println("Oh no, we couldn't pet the cat!")
        exit(1)
    }

    println('Great, we could pet the cat ' + cat_name)
}

fn get_pet_cat_name() !string {
    if cat_found { return 'Max' } 
    else { return error('the cat is nowhere to be found') }
}

See also

[edit]

References

[edit]
  1. ↑ "std::expected - cppreference.com". en.cppreference.com. 25 August 2023. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  2. ↑ "Result · An Introduction to Elm". guide.elm-lang.org. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  3. ↑ "Data.Either". hackage.haskell.org. 22 September 2023. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  4. ↑ "Result - Kotlin Programming Language". kotlinlang.org. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  5. ↑ "Error Handling · OCaml Tutorials". ocaml.org. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  6. ↑ "std::result - Rust". doc.rust-lang.org. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  7. ↑ "stdlib: Add result module · rust-lang/rust@c1092fb". github.com. 29 October 2011. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  8. ↑ "Scala Standard Library 2.13.12 - scala.util.Either". www.scala-lang.org. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  9. ↑ "Result | Apple Developer Documentation". developer.apple.com. Archived from the original on 9 October 2023. Retrieved 9 October 2023.
  10. ↑ cppreference.com (19 August 2026). "std::unexpect_t, std::unexpect". cppreference.com. cppreference.com.
  11. ↑ cppreference.com (19 August 2026). "std::bad_expected_access". cppreference.com. cppreference.com.