Last active
March 27, 2016 10:55
-
-
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
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 <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