Skip to content

Instantly share code, notes, and snippets.

@daniel-j-h
Last active March 27, 2016 10:55
Show Gist options
  • Save daniel-j-h/2034b5de574928034d82 to your computer and use it in GitHub Desktop.
Save daniel-j-h/2034b5de574928034d82 to your computer and use it in GitHub Desktop.
Read about the Free Monad here: http://degoes.net/articles/modern-fp
#include <string>
#include <vector>
#include <iterator>
#include <iostream>
#include <boost/variant.hpp>
// http://degoes.net/articles/modern-fp
struct CloudFilesF final {
struct SaveFile final {
std::string const path;
unsigned char const* const bytes;
};
struct ListFiles final {
std::string const path;
};
boost::variant<SaveFile, ListFiles> const constructor;
};
auto saveFile(const std::string& path, unsigned char const* const bytes) { //
return CloudFilesF{CloudFilesF::SaveFile{path, bytes}};
}
auto listFiles(const std::string& path) { //
return CloudFilesF{CloudFilesF::ListFiles{path}};
}
struct HttpF final {
struct Get final {
std::string const path;
};
struct Post final {
std::string const path;
unsigned char const* const bytes;
};
boost::variant<Get, Post> const constructor;
};
auto httpGet(const std::string& path) { //
return HttpF{HttpF::Get{path}};
}
auto httpPost(const std::string& path, unsigned char const* const bytes) { //
return HttpF{HttpF::Post{path, bytes}};
}
auto cloudFilesI(const CloudFilesF& f) {
struct final {
auto operator()(const CloudFilesF::SaveFile& sf) const { //
return std::vector<HttpF>{httpPost(sf.path, sf.bytes)};
}
auto operator()(const CloudFilesF::ListFiles& lf) const { //
return std::vector<HttpF>{httpGet(lf.path)};
}
} const match{};
return apply_visitor(match, f.constructor);
}
auto executor(const std::vector<HttpF>& fs) {
struct final {
auto operator()(const HttpF::Get& get) const { //
std::cout << "GET " << get.path << std::endl;
}
auto operator()(const HttpF::Post post) const { //
std::cout << "Post " << post.path << std::endl;
}
} const match{};
for (auto const& each : fs)
apply_visitor(match, each.constructor);
}
int main() {
auto const save = saveFile("/to", nullptr);
auto const list = listFiles("/from");
auto const saveHttp = cloudFilesI(save);
auto const listHttp = cloudFilesI(list);
executor(saveHttp);
executor(listHttp);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment