All Projects → LoopPerfect → Neither

LoopPerfect / Neither

Licence: mit
Either and Maybe monads for better error-handling in C++ ↔️

Programming Languages

cpp
1120 projects

Projects that are alternatives of or similar to Neither

Language Ext
C# functional language extensions - a base class library for functional programming
Stars: ✭ 3,964 (+1579.66%)
Mutual labels:  monads, functional-programming
Learn Fp
learn-by-doing course/tutorial for functional programming on scala
Stars: ✭ 548 (+132.2%)
Mutual labels:  monads, functional-programming
True Myth
A library for safer and smarter error- and "nothing"-handling in TypeScript.
Stars: ✭ 360 (+52.54%)
Mutual labels:  monads, functional-programming
Pratica
🥃 Functional Algebraic Data Types
Stars: ✭ 246 (+4.24%)
Mutual labels:  monads, functional-programming
Funcj
Assorted functional-oriented data structures and algorithms for Java.
Stars: ✭ 60 (-74.58%)
Mutual labels:  monads, functional-programming
Monio
Async-capable IO monad for JS
Stars: ✭ 311 (+31.78%)
Mutual labels:  monads, functional-programming
Arrow
Λrrow - Functional companion to Kotlin's Standard Library
Stars: ✭ 4,771 (+1921.61%)
Mutual labels:  monads, functional-programming
Mu Scala
Mu is a purely functional library for building RPC endpoint based services with support for RPC and HTTP/2
Stars: ✭ 266 (+12.71%)
Mutual labels:  monads, functional-programming
Purefun
Functional Programming library for Java
Stars: ✭ 37 (-84.32%)
Mutual labels:  monads, functional-programming
Kea
Composable Functional Programming in R
Stars: ✭ 18 (-92.37%)
Mutual labels:  monads, functional-programming
Whyhaskellmatters
In this article I try to explain why Haskell keeps being such an important language by presenting some of its most important and distinguishing features and detailing them with working code examples. The presentation aims to be self-contained and does not require any previous knowledge of the language.
Stars: ✭ 418 (+77.12%)
Mutual labels:  monads, functional-programming
Scala Workflow
Boilerplate-free syntax for computations with effects
Stars: ✭ 173 (-26.69%)
Mutual labels:  monads, functional-programming
Freestyle
A cohesive & pragmatic framework of FP centric Scala libraries
Stars: ✭ 627 (+165.68%)
Mutual labels:  monads, functional-programming
Fpgo
Monad, Functional Programming features for Golang
Stars: ✭ 165 (-30.08%)
Mutual labels:  monads, functional-programming
Maryamyriameliamurphies.js
A library of Haskell-style morphisms ported to ES2015 JavaScript using Babel.
Stars: ✭ 177 (-25%)
Mutual labels:  monads, functional-programming
Eta
The Eta Programming Language, a dialect of Haskell on the JVM
Stars: ✭ 2,507 (+962.29%)
Mutual labels:  functional-programming
Functional intro to python
[tutorial]A functional, Data Science focused introduction to Python
Stars: ✭ 228 (-3.39%)
Mutual labels:  functional-programming
Bitcoin Chart Cli
Bitcoin chart for the terminal as command line util
Stars: ✭ 221 (-6.36%)
Mutual labels:  functional-programming
React Organism
Dead simple React state management to bring pure components alive
Stars: ✭ 219 (-7.2%)
Mutual labels:  functional-programming
Curryhoward
Automatic code generation for Scala functions and expressions via the Curry-Howard isomorphism
Stars: ✭ 229 (-2.97%)
Mutual labels:  functional-programming

neither

A functional implementation of Either in C++14.

Travis GitHub license

buckaroo add github.com/loopperfect/neither

Examples

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 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 proper handling by the API consumer

Installation

This library requires a C++ 14 compiler.

Install with Buckaroo:

buckaroo add github.com/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
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].