Git Product home page Git Product logo

neither's Introduction

Sponsor

neither

A functional implementation of Either in C++14.

buckaroo install loopperfect/neither

Introductory Example

Handling Unsafe code

auto unsafe = [] { // a function that throws, sometimes we can't avoid it...
  if (true) {
    throw std::runtime_error("error");
  }
  return 1;
}

Either<std::exception, int> e = Try<std::exception>(unsafe); // let's lift the exception into the typesystem

e.left()
  .map([](auto const& e) { 
    return std::cerr << e.what() << std::endl; 
  }); // print error if available

int result = e
  .leftMap([](auto) { return 42; }) // do nothing with exception and map to 42
  .rightMap([](auto x) { return x * 2; }) // do further computation if value available
  .join() // join both sides of either
  
ASSERT_TRUE(result == 42);

Another Either Example

Either<std::string, int> compute(int x) {
  if(x<0) return left("don't pass x<0");
  return right(x*x);
}

std::string resultString = compute(5)
  .rightMap([](auto x){ return x/2.0;}) // success case
  .join(
    [](auto errorStr) { return "compute said: " + errorStr; }, // error-case
    [](auto x) { return "compute said: " + std::to_string(x); } // success-case
   );
   
std::cout << resultString << std::endl;

Composition of Eithers

neither::Either<my_error_t, int> f1();
neither::Either<my_error_t, float> f2();

void compose() {
    auto value = f1()
        .rightFlatMap([](const struct_a& v){
            return f2();
        })
        .rightMap([](const struct_b& v){
            return 5;
        })
        .leftMap([](const auto& my_error){
            return 6;
        }).join();
    // value should be either 5 or 6
}

Maybe Example

Maybe<float> compute(float x) {
  if(x<0) return {};
  return {sqrtf(x)};
}

Maybe<float> x = compute(-4)
 .map([](auto x){ return x*x;})
 .map([](auto x){ return x+1 });
 
if(!x.hasValue) {
  std::cerr << "error occured" << std::endl;
}
 

Monadic Lifting

int sum(int x, int y){ return x+y; }

//...

auto monadicSum = lift(sum); // transforms sum to: Maybe<int> MonadicSum(Maybe<int>, Maybe<int>)

ASSERT_TRUE( monadicSum( maybe(5) , maybe(7) ).get(0) == 12 );
ASSERT_TRUE( monadicSum( maybe(), maybe(1) ).hasValue == false);
 

Why Eithers? - Learned Lessons About Error handling

Some useful references:

Summary and Conclusions

  • Error codes break composition
    • requires out-parameters; making functions impure and hard to reason about
    • using out-parameters makes inlining harder
    • => don't use output parameters
  • Exceptions are 2-3 orders of magnitude slower if exceptions are thrown
    • => avoid throwing exceptions - not always possible
  • Overhead of exceptions grows linear with the callstack
    • => catch exceptions early
  • Exceptions are not part of the type-system
    • annotating function signatures with throw and noexcept is not helpful; contract breaches are not detected in compile-time but call std::terminate in run-time
    • handling exceptions is error prone and requires documentation
    • => encode errors in the types to enforce propper handling by the API consumer

Installation

This library requires a C++ 14 compiler.

Install with Buckaroo:

buckaroo install loopperfect/neither

The Buck target is :neither

Alternatively you can copy & paste the headers to your include path:

cp neither/include/*.hpp $InstallPath/include/neither

Sponsor

neither's People

Contributors

nikhedonia avatar njlr avatar dvdfreitag avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.