Haskellなどにあるunfoldは、reduceの逆で初期値からリストを作っていきます。
f(状態0) → (値1, 状態1) → 値1
f(状態1) → (値2, 状態2) → 値2
という具合に値を出していきます。
reduceの逆なのにunfoldなのはあまり気にしない方向で。
template<typename T, typename U, typename V> class cUnfold : public cIterable<T> { T val; U stat; V func; public: cUnfold(V f, U s) : stat(s), func(f) { } bool exists_next() { pair<T,U> p = func(stat); val = p.first; stat = p.second; return true; } T value() const { return val; } }; template<typename U, typename V> auto unfold(V f, U s) -> shared_ptr<cIterable<decltype(f(s).first)>> { typedef decltype(f(s).first) T; return shared_ptr<cIterable<T>>(new cUnfold<T,U,V>(f, s)); }
これで、フィボナッチ数列が簡単に作れます。
shared_ptr<cIterable<int>> fib() { typedef pair<int,int> T; auto f = [] (T s) { return pair<int,T>(s.second, T(s.second, s.first + s.second)); }; return unfold(f, T(1, 1)); }