boost :: hana: Почему я не могу отфильтровать сет? - PullRequest
0 голосов
/ 30 сентября 2018

Я использую boost :: hana, и я хотел бы отфильтровать boost :: hana :: set.

#include <boost/hana.hpp>
#include <type_traits>

int main(){
    using namespace boost::hana;
    auto a = make_set(1,'a',3);
    auto b = remove_if(a, [](const auto& x){return bool_c<std::is_same_v<decltype(x), char>>;});
    // expects b to be make_set(1, 3);
}

Это приводит к ошибке static_assert.Он говорит мне:

static assertion failed: hana::remove_if(xs, predicate) requires 'xs' to be a MonadPlus

         static_assert(hana::MonadPlus<M>::value, 

Почему это не удается?Почему набор не может быть MonadPlus, даже если определены пустой набор и операция конкатенации?

1 Ответ

0 голосов
/ 01 октября 2018

Если вы хотите отфильтровать список, вы должны использовать hana::tuple.Идея набора более общая, чем MonadPlus или даже Monad.Ваше утверждение о том, что hana::set имеет реализации для hana::concat или hana::empty, неверно и, кроме того, требует, чтобы структура данных была монадой.

Исходя из вашего примера, возможно, вы ищетеhana::difference, но hana::set сам по себе довольно бесполезен для этого.Его операции требуют hana::Comparable и плохо работают с состоянием времени выполнения.

Если вы хотите «фильтровать» наборы по их типу и поддерживать значения времени выполнения, я предлагаю использовать hana::map, что такжеподдерживает операции над множествами.Вы можете сделать его ключи hana::type его значения.Это все еще требует уникальности по типу.

Вот пример:

#include <boost/hana.hpp>

namespace hana = boost::hana;

constexpr auto typed_set = [](auto&& ...x) {
  return hana::make_map(
    hana::make_pair(hana::typeid_(x), std::forward<decltype(x)>(x))...
  );
};

int main() {
  auto a = typed_set(1, 'a', 3.0f);
  auto b = typed_set('c');
  auto c = hana::difference(a, b);

  BOOST_HANA_RUNTIME_ASSERT(c == typed_set(1, 3.0f));
}
...