加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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>();
    };
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读