固有のの機能をA --> Monad<B>
に提供し、それが正しいことを確認することです。無限再帰を防止するために、私たちはA --> M
機能するかどうかを確認することができます
template <class M>
concept bool Monad()
{
return requires(M m) {
{ m >>= std::function<M(ValueType<M>)>{} } -> M;
};
}
これが唯一の特定のケースですが、私は一般的なケースを検証することが可能であるとは考えていないことからA --> Monad<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>;
};
}
独自のサブにそのリファクタリングによって容易に得るかもしれません-concept: `演算子を使用して>>さておき、(AB)として
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>();
};
}
='ここでのミスのように思えます。 C++では 'a >> = b >> = c'は' a >> =(b >> = c) 'として関連付けられ、ハスケルでは'(a >> = b)>> = c'として関連付けられます。 –
ええ私は知っている:)明らかに生産価値のあるコードではない - ちょうど概念について少し学ぶための遊びを持っている –