Skip to content

Instantly share code, notes, and snippets.

@b4284
Created May 7, 2018 16:28
Show Gist options
  • Save b4284/63df53da573f163da0cded42fc5fddbf to your computer and use it in GitHub Desktop.
Save b4284/63df53da573f163da0cded42fc5fddbf to your computer and use it in GitHub Desktop.
#include <cmath>
#include <functional>
#include <iostream>
using std::function;
using std::cout;
using std::endl;
template<class A> class optional {
bool _isValid;
A _value;
public:
optional() : _isValid(false) {}
optional(A v) : _isValid(true), _value(v) {}
bool isValid() const { return _isValid; }
A value() const { return _value; }
void print() {
if (_isValid) {
cout << _value << endl;
} else {
cout << "invalid!" << endl;
}
}
};
optional<double> safe_root(double x) {
if (x >= 0) return optional<double>{sqrt(x)};
else return optional<double>{};
}
optional<double> safe_reciprocal(double x) {
if (x != 0) return optional<double>{1/x};
else return optional<double>{};
}
template<class A, class B, class C>
function<optional<C>(A)> compose(function<optional<B>(A)> m1,
function<optional<C>(B)> m2)
{
return [m1, m2](A a) {
auto p1 = m1(a);
if (!p1.isValid()) {
return optional<C>{};
}
auto p2 = m2(p1.value());
if (!p2.isValid()) {
return optional<C>{};
}
return optional<C>(p2.value());
};
}
template<class A>
optional<A> identity(A a) {
return optional<A>(a);
}
int main() {
auto c = compose<double, double, double>(identity<double>, safe_root);
auto d = compose<double, double, double>(c, safe_reciprocal);
auto r1 = d(4);
auto r2 = d(-1);
r1.print();
r2.print();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment