boost::hana: 为什么我不能过滤集合?
boost::hana: Why can't I filter a set?
我正在使用 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,即使定义了空集合和串联操作?
如果你想过滤一个列表,你应该使用 hana::tuple
。 Set 的概念比 MonadPlus 甚至 Monad 更通用。您断言 hana::set
具有 hana::concat
或 hana::empty
的实现是不正确的,此外它还要求数据结构是 Monad。
根据您的示例,也许您正在寻找的是 hana::difference
,但 hana::set
本身对此毫无用处。它的操作需要 hana::Comparable
并且在 运行 时间状态下表现不佳。
如果你想 "filter" 按类型设置并保持 运行 时间值,我建议使用 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));
}
我正在使用 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,即使定义了空集合和串联操作?
如果你想过滤一个列表,你应该使用 hana::tuple
。 Set 的概念比 MonadPlus 甚至 Monad 更通用。您断言 hana::set
具有 hana::concat
或 hana::empty
的实现是不正确的,此外它还要求数据结构是 Monad。
根据您的示例,也许您正在寻找的是 hana::difference
,但 hana::set
本身对此毫无用处。它的操作需要 hana::Comparable
并且在 运行 时间状态下表现不佳。
如果你想 "filter" 按类型设置并保持 运行 时间值,我建议使用 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));
}