Result type

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

  • 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 Result<R, E> similar to Rust Result<T, E>, and vavr includes an interface Either<L, R> similar to Haskell Either a b. Because Java and Kotlin are cross-compatible, Java can use the Result type from Kotlin.
  • In Kotlin, it is defined by the standard library as value class Result<out 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 enum Result<T, E> { Ok(T), Err(E) }.[6][7]
  • 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++

The 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();
        }
    }
}

Rust

Enums in Rust are tagged unions, which can be unpacked with strong type checking through pattern matching.

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

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

References

  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.

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.