Maybeモナドみたいなものが作りたかった

メタプログラミング難しいし、モナド則にちゃんと則ってるかよくわかんないし。

メタプログラミング難しいし、モナド則にちゃんと則ってるかよくわかんないし。

  • タグ:
  • タグはありません
#include <cstdio>
#include <boost/optional.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
template <typename T>
struct is_optional : public boost::false_type
{ };
template <typename T>
struct is_optional<boost::optional<T> > : public boost::true_type
{ };
template <typename T, typename F,
typename Reserver = typename boost::disable_if<is_optional<typename boost::result_of<F(T)>::type>>::type,
typename Reserver2 = typename boost::disable_if<boost::is_void<typename boost::result_of<F(T)>::type>>::type
>
inline boost::optional<typename boost::result_of<F(T)>::type> operator >> (boost::optional<T> val, F func)
{
if (val) {
return func(*val);
} else {
return boost::none;
}
}
template <typename T, typename F, typename Reserver = typename boost::enable_if<is_optional<typename boost::result_of<F(T)>::type>>::type>
inline typename boost::result_of<F(T)>::type operator >> (boost::optional<T> val, F func)
{
if (val) {
return func(*val);
} else {
return boost::none;
}
}
template <typename T, typename F, typename Reserver = typename boost::enable_if<boost::is_void<typename boost::result_of<F(T)>::type>>::type>
inline void operator >> (boost::optional<T> val, F func)
{
if (val) {
return func(*val);
}
}
boost::optional<int> testFunc(int n) {
return (n % 2 == 0)? n/2 : boost::optional<int>();
}
int testFunc2(int n) {
return n / 2;
}
int main(int argc, const char * argv[])
{
testFunc(32)
>> [] (int r) { return testFunc(r); }
>> [] (int r) { return testFunc2(r); }
>> [] (int r) { std::printf("%d", r); }
;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX