TMP で Maybe モナド
namespace monad { namespace maybe { struct nothing { }; template<class A> struct just { }; template<class A> struct ret { typedef just<A> type; }; template<class M, template<class> class F> struct bind; template<class A, template<class> class F> struct bind<just<A>, F> { typedef typename F<A>::type type; }; template<template<class> class F> struct bind<nothing, F> { typedef nothing type; }; } }
定義を見ながら作るだけなのでこれは簡単。
例が思いつかなかったので C++でMaybeモナドを返すlookup関数を作ってみた - Faith and Brave - C++で遊ぼう のおまけを参考にしてみました。
template<class A> struct inc; template<int N> struct inc<int_<N>> { typedef typename if_<bool_<(N >= 10)>, monad::maybe::nothing, typename monad::maybe::ret<int_<N + 1>>::type>::type type; }; int main() { using namespace monad::maybe; typedef int_<8> value; typedef bind<ret<value>::type, inc>::type ret1; typedef bind<bind<ret<value>::type, inc>::type, inc>::type ret2; typedef bind<bind<bind<ret<value>::type, inc>::type, inc>::type, inc>::type ret3; typedef bind<bind<bind<bind<ret<value>::type, inc>::type, inc>::type, inc>::type, inc>::type ret4; static_assert(is_same<just<int_<9>>, ret1>::value, "failed"); static_assert(is_same<just<int_<10>>, ret2>::value, "failed"); static_assert(is_same<nothing, ret3>::value, "failed"); static_assert(is_same<nothing, ret4>::value, "failed"); }
operator>>= が使えないといろいろ無理がある気がする……。