Mam całkiem prostą funkcję flatmap
zaimplementowaną w C++ dla std::vector
, ale zasugerowano, że zakresy są ogólnie lepsze. Oto rozwiązanie wektor oparty:Jak zaimplementować mapę płaską przy użyciu zakresów rangev3
// flatmap: [A] -> (A->[B]) -> [B]
template<typename T, typename FN>
static auto flatmap(const std::vector<T> &vec, FN fn)
-> std::vector<typename std::remove_reference<decltype(fn(T())[0])>::type> {
std::vector<typename std::remove_reference<decltype(fn(T())[0])>::type> result;
for(auto x : vec) {
auto y = fn(x);
for(auto v : y) {
result.push_back(v);
}
}
return result;
};
Stwierdzono również zasugerował, że mogę używać iteratory, ale łamie piękny composability funkcji:
map(filter(flatmap(V, fn), fn2), fn3)
Przypuszczam, że w świecie gama-V3 byłbym zmierzające do pisania powyższego jako:
auto result = v | flatmap(fn) | filter(fn2) | transform(fn3);
czuje się jak flatmap
powinny być po prostu banalne połączenie views::for_each
, yield_from
i transform
, ale staram się dowiedzieć, jak połączyć je wszystkie razem.