I'm trying to implement few higher order functions from Haskell in C++. Below are the definitions of takeWhile
, groupBy
, and group
.
I would appreciate it if someone can review and comment if the implementation takes care of all scenarios. Should I be using universal refs for parameters to these functions? Please let me know of any other comments, too. Please assume C++14 standard and above. Also, if there are existing implementations that I can use to study and refer to, please point me to them too.
#include <vector>
#include <utility>
template <typename fwd_iter, typename predicate>
auto takeWhile(fwd_iter first, fwd_iter last, predicate p) -> std::pair<fwd_iter, fwd_iter>
{
auto till = (first);
for (; till != last; till++) {
if (!p(*till)) {
break;
}
}
return { first, till };
}
// something similar to std::greater or std::less.. is there something for equality??
struct equal {
template <typename T>
constexpr bool operator()(const T &lhs, const T &rhs) const
{
return lhs == rhs;
}
};
// predicate type should be : typename *fwd_iter -> typename *fwd_iter -> bool)
template <typename fwd_iter, typename predicate,
typename container = std::vector<std::pair<fwd_iter, fwd_iter>>>
auto groupBy(fwd_iter first, fwd_iter last, predicate pred)
{
auto current = first;
container ret;
while (current != last) {
auto t = takeWhile(current, last, [&](auto x) {return pred(*current, x); });
current = t.second;
ret.emplace_back(t);
}
return ret;
}
template <typename fwd_iter>
auto group (fwd_iter first, fwd_iter last)
{
return groupBy(first, last, equal());
}