某所で挙がっていたことが気になった.ので,適当にググって発見したhttp://pc.2ch.net/tech/kako/996/996131288.htmlの169に書いてあったことを,おおよそそのまんまC++とBLLの形に翻訳してみた結果(と普通の再帰での書き方)が以下.
#include <iostream>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/if.hpp>
template<class F>
struct fixer;
template<class F>
fixer<F> fix(F f)
{
return fixer<F>(f);
}
template<class F>
struct fixer
{
fixer(F f)
: f_(f)
{ }
template<class T>
T operator()(T n)
{
return f_(fix(f_), n);
}
F f_;
};
int main()
{
using namespace std;
using namespace boost;
using namespace boost::lambda;
// 上の記事に従うと以下
function<int (function<int (int)>, int)> f
= ret<int>(if_then_else_return(_2 == 1, cref(1), bind(_1, _2 - 1) * _2));
cout << fix(f)(1) << '\n';
cout << fix(f)(2) << '\n';
cout << fix(f)(3) << '\n';
cout << fix(f)(4) << '\n';
cout << fix(f)(5) << '\n';
cout << fix(f)(6) << '\n';
// 普通の再帰で書くと以下
function<int (int)> g;
g = ret<int>(if_then_else_return(_1 == 1, cref(1), bind(var(g), _1 - 1) * _1));
cout << g(1) << '\n';
cout << g(2) << '\n';
cout << g(3) << '\n';
cout << g(4) << '\n';
cout << g(5) << '\n';
cout << g(6) << '\n';
}うむ.要するに黙っておとなしく関数にしときなさいってことですな.頑張れば汎用かつ分かりやすいものが作れるような気もするけど,そんなの考えてる/作ってるヒマがにゃい・・・.