C概念:我可以定义一个本身就是模板的概念吗?
发布时间:2020-12-16 07:16:04 所属栏目:百科 来源:网络整理
导读:对不起,如果问题不太清楚.我不确定用它来表达它的最佳方式(随意编辑!).我认为一个例子是最清楚的: 我试图定义一个基于Haskell definition的Monad概念.绑定运算符( =)要求A类型的Monad可以绑定到一个带有A的函数并返回一个B类型的Monad.可以根据value_type
对不起,如果问题不太清楚.我不确定用它来表达它的最佳方式(随意编辑!).我认为一个例子是最清楚的:
我试图定义一个基于Haskell definition的Monad概念.绑定运算符(>> =)要求A类型的Monad可以绑定到一个带有A的函数并返回一个B类型的Monad.可以根据value_type typedef定义A,但如何在我的概念中定义类型B? template <typename M> concept bool Monad() { return requires(M m,Function<_1,ValueType<M>> f) { // (>>=) :: m a -> (a -> m b) -> m b { m >>= f } -> M } } 在上面的例子中,我在Function<>中用什么来代替_1?概念? 这也足以将调用f的结果限制为任何类型的Monad吗? 解决方法
我认为你能做的最接近的是提供一个特定的功能,即A – >单子< B个并验证它做对了.为了防止无限递归,我们可以验证A – > M作品:
template <class M> concept bool Monad() { return requires(M m) { { m >>= std::function<M(ValueType<M>)>{} } -> M; }; } 这只是一个具体案例,但我不相信有可能验证A – >的一般情况.单子< X>因为概念检查仍然涉及特定表达式,您只能创建具有特定类型的特定表达式. 当然,我们可以提供多种此类要求.使用重新绑定元函数: template <class M,class X> struct rebind; template <class M,class X> using rebind_t = typename rebind<M,X>::type; template <template <class...> class Z,class R,class X> struct rebind<Z<R>,X> { using type = Z<X>; }; 然后我们可以为返回各种类型的函数添加需求,比如它也适用于int: template <class M> concept bool Monad() { return requires(M m) { { m >>= std::function<M(ValueType<M>)>{} } -> M; { m >>= std::function<rebind_t<M,int>(ValueType<M>)>{} } -> rebind_t<M,int>; }; } 通过将其重构为自己的子概念可能会变得更容易: template <class M,class R> concept bool MonadBind() { return requires(M m) { { m >>= std::function<rebind_t<M,R>(ValueType<M>)>{} } -> rebind_t<M,R>; }; } template <class M> concept bool Monad() { return requires(M m) { requires MonadBind<M,ValueType<M>>(); requires MonadBind<M,int>(); }; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |