Last active
February 21, 2020 06:11
-
-
Save kylehovey/0337429cad420252a74f51877c9e1c1f to your computer and use it in GitHub Desktop.
Observable subscription model with minimal side-effects
This file contains hidden or 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 <functional> | |
#include <vector> | |
#include <iostream> | |
namespace Observable { | |
template <typename D> | |
using Callback = std::function<void(const D&)>; | |
template <typename D, typename R> | |
using Morphism = std::function<R(D)>; | |
template <typename D> | |
using Endo = Morphism<D, D>; | |
template <typename D> | |
using Subscriptions = std::vector<Callback<D>>; | |
const auto unit = [](const auto& message) { return message; }; | |
const auto print = [](const auto& message) { std::cout << message << std::endl; }; | |
template <typename D> | |
class Observable { | |
public: | |
Observable(): transmutation(unit) {} | |
Observable(const Endo<D>& transmutation): transmutation(transmutation) {} | |
Observable( | |
const Subscriptions<D>& subscriptions, | |
const Endo<D>& transmutation | |
): subscriptions(subscriptions), transmutation(transmutation) {} | |
const Observable<D> subscribe(const Callback<D>& callback) const { | |
auto subscriptions = this->subscriptions; | |
subscriptions.push_back(callback); | |
return Observable<D>( | |
subscriptions, | |
this->transmutation | |
); | |
} | |
const Observable<D> map(const Endo<D>& mutate) const { | |
return Observable<D>( | |
[=](const auto& message) { | |
return mutate(this->transmutation(message)); | |
} | |
); | |
} | |
const Observable<D> post(const D& message) const { | |
for (const auto& callback : this->subscriptions) { | |
callback(this->transmutation(message)); | |
} | |
return *this; | |
} | |
private: | |
const Subscriptions<D> subscriptions; | |
const Monoid<D> transmutation; | |
}; | |
} | |
int main() { | |
Observable::Observable<double>() | |
.subscribe(Observable::print) | |
.post(25) | |
.map([](const double& message) { return message * message; }) | |
.map([](const double& message) { return message * message; }) | |
.subscribe(Observable::print) | |
.post(25); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment