Skip to content

Instantly share code, notes, and snippets.

@kylehovey
Last active February 21, 2020 06:11
Show Gist options
  • Save kylehovey/0337429cad420252a74f51877c9e1c1f to your computer and use it in GitHub Desktop.
Save kylehovey/0337429cad420252a74f51877c9e1c1f to your computer and use it in GitHub Desktop.
Observable subscription model with minimal side-effects
#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