make_monadic

Synopsis

template <class MonadTag, class Expr>
struct make_monadic
{
  // unspecified
};

Description

Given a monadic action of the maybe monad

MPLLIBS_METAFUNCTION(f, (N)) ((just<N>));

A metafunction for division is also given:

MPLLIBS_METAFUNCTION(maybe_divides, (A)(B)) ((just<divides<A, B>>));

To divide the result of f<int_<26>> to f<int_<2>> one has to use bind or a do block. For example:

do_c<
  maybe_tag,
  set<a, f<int_<26>>>,
  set<b, f<int_<2>>>,
  maybe_divides<a, b>
>

Writing

maybe_divides<f<int_<26>, int_<2>>>

would be invalid, since maybe_divides expects numbers and not Maybe numbers. make_monadic expects such an invalid expression and turns it into a valid monadic expression:

make_monadic<
  maybe_tag,
  syntax<
    maybe_divides<already_monadic<f<int_<26>>>, already_monadic<f<int_<2>>>>
  >
>

The subexpressions that should not be transformed should be marked with already_monadic.

#include <mpllibs/metamonad/make_monadic.hpp>

Expression semantics

For any monad_tag tag, n > 0, f metafunction taking n arguments and t, t1, ..., tn classes the following are equivalent:

make_monadic<monad_tag, syntax<t>>::type
t::type
make_monadic<monad_tag, syntax<f<t1, ..., tn>>::type
do_c<
  set<t1_, make_monadic<monad_tag, syntax<t1>>>,
  // ...
  set<tn_, make_monadic<monad_tag, syntax<tn>>>,
  f<t1_, ..., tn_>
>::type

Example

MPLLIBS_METAFUNCTION(f, (N)) ((just<N>));
MPLLIBS_METAFUNCTION(maybe_divides, (A)(B)) ((just<divides<A, B>>));

make_monadic<
  maybe_tag,
  syntax<
    maybe_divides<already_monadic<f<int_<26>>>, already_monadic<f<int_<2>>>>
  >
>::type

[up]