reduce

sumを作りたいのですが、その前にPythonでreduceと言ったり、Haskellでfoldと言ったりするものを作ります。リストなどに関数を次々に適用してスカラー値にするものです。(1, 2, 3)にf(x, y) = 10x + yを適用していくと、初期値を0として、

10 * 0 + 1 -> 1
10 * 1 + 2 -> 12
10 * 12 + 3 -> 123

と10進数になります。
reduceは関数なので簡単に書けます。初期値は必須としました。

template<typename T, typename U, typename V>
T reduce(U f, shared_ptr<cIterable<V>> g, T init) {
    while(g->exists_next())
        init = f(init, g->value());
    return init;
}

int main() {
    cout << reduce([] (int x, int y) { return x * 10 + y; },
                                    range(1, 4), 0) << endl;
}

reduceを使ってsumが定義できます。

template<typename T>
T sum(shared_ptr<cIterable<T>> g) {
    return reduce([] (int x, int y) { return x + y; }, g, 0);
}

これでやっと、Project Euler Problem 1が書けます。

int main() {
    const int   N = 1000;
    auto    f = [] (int n) { return n % 3 == 0 || n % 5 == 0; };
    cout << sum(filter(f, range(1, N))) << endl;
}