Skip to content

Instantly share code, notes, and snippets.

@ifd3f
Created March 20, 2024 06:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ifd3f/be508885746961ed7ef2dae3b6487eaf to your computer and use it in GitHub Desktop.
Save ifd3f/be508885746961ed7ef2dae3b6487eaf to your computer and use it in GitHub Desktop.
#include <functional>
#include <iostream>
#include <memory>
#include <optional>
#include <sstream>
#include <string>
template <class A> class Maybe {
std::unique_ptr<A> contents;
Maybe(std::unique_ptr<A> contents) : contents(std::move(contents)) {}
Maybe() {}
public:
static Maybe<A> Just(A a) { return Maybe(std::make_unique<A>(a)); }
static Maybe<A> Nothing() { return Maybe(); }
bool is_just() const { return this->contents != nullptr; }
const A &unwrap() const {
if (this->contents) {
return *this->contents;
}
throw "failed to unwrap nothing";
}
template <class B> auto operator>>=(std::function<Maybe<B>(const A &)> f) {
if (this->is_just()) {
return f(this->unwrap());
}
return Maybe<B>::Nothing();
}
};
template <class A>
std::ostream &operator<<(std::ostream &os, const Maybe<A> &obj) {
if (obj.is_just()) {
return os << "Just(" << obj.unwrap() << ")";
} else {
return os << "Nothing";
}
}
int main() {
Maybe<int> obj1 = Maybe<int>::Just(10);
Maybe<int> obj2 = Maybe<int>::Nothing();
std::function<Maybe<int>(const int &)> action =
([](const int &a) { return Maybe<int>::Just(a + 10); });
Maybe<int> newthing1 = (obj1 >>= action);
Maybe<int> newthing2 = (obj2 >>= action);
Maybe<int> compose_twice = ((obj1 >>= action) >>= action);
std::cout << "Hello World!\n"
<< obj1 << " becomes " << newthing1 << "\n"
<< obj2 << " becomes " << newthing2 << "\n"
<< "Composed twice: " << compose_twice;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment