Created
May 7, 2018 16:28
-
-
Save b4284/63df53da573f163da0cded42fc5fddbf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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