Skip to content

Instantly share code, notes, and snippets.

@lion137
Last active October 30, 2019 08:54
Show Gist options
  • Save lion137/6da6b8340837f4bdd85634b615bceb2a to your computer and use it in GitHub Desktop.
Save lion137/6da6b8340837f4bdd85634b615bceb2a to your computer and use it in GitHub Desktop.
Optional in C++ as Kleisli Category
#include <iostream>
#include <cmath>
#include <vector>
/* More info and explanation here: https://lion137.blogspot.com/2019/01/kleisli-category-by-example.html */
template<class A> class optional {
bool _isValid;
A _value;
public:
optional(): _isValid(false) {}
optional(A e) : _isValid(true), _value(e) {}
optional(A e, bool v) : _isValid(v), _value(e) {}
A value() const { return _value; }
bool validation() const {return _isValid;}
};
optional<double> safe_root(double x);
optional<double> safe_reciprocal(double x);
optional<double> identity(double x);
//composition
auto const compose = [](auto m1, auto m2) {
return [m1, m2](auto x) {
auto p1 = m1(x);
auto p2 = m2(p1.value());
return optional<double>(p2.value(), p1.validation() && p2.validation());
};
};
int main () {
auto const safe_root_reciprocal = compose(safe_reciprocal, safe_root);
auto const safe_rootIdR = compose(safe_root, identity);
auto const safe_rootIdL = compose(identity, safe_root);
std::cout << safe_root_reciprocal(0).validation() << "\n"; // -> 0
std::cout << safe_root_reciprocal(3).validation() << "\n"; // -> 1
std::cout << safe_root_reciprocal(3).value() << "\n"; // -> 0.57735
std::cout << (safe_rootIdR(2).value()) << "\n"; // -> 1.41421
std::cout << (safe_rootIdL(2).value()) << "\n"; // -> 1.41421
std::vector<int> myVector{1};
myVector.pop_back();
for (auto & e : myVector)
std::cout << e << " ";
}
optional<double> safe_root(double x) {
if (x >= 0) return optional<double>{std::sqrt(x)};
else return optional<double>{};
}
optional<double> safe_reciprocal(double x) {
if (! x == 0) return optional<double> {1 / x};
else return optional<double>{};
}
//identity
optional<double> identity(double x) {
return optional<double>{x};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment