#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
template <typename Container, typename F>
Container Map(F f, Container xs )
{
Container ys;
auto it = std::inserter( ys, end( ys ) );
std::transform( begin( xs ), end( xs ), it, f );
return ys;
}
template <typename Ret, typename Arg1, typename... Args>
auto Curry(Ret (*f)(Arg1, Args...), Arg1 arg ) -> std::function<Ret(Args...)>
{
return [=]( Args... args ) { return f( arg, args... ); };
}
int main()
{
auto square = [](int x){ return x*x; };
typedef std::vector<int> Row;
Row row = {1, 2 , 3};
Row squaredRow = Map(square, row);
typedef std::vector<Row> Mat;
Mat mat = {{1,2},{2,3,4}};
auto squareElements = Curry(Map<Row, decltype(square)>, square);
Mat squaredMat = Map(squareElements, mat);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdGVtcGxhdGUgPHR5cGVuYW1lIENvbnRhaW5lciwgdHlwZW5hbWUgRj4KQ29udGFpbmVyIE1hcChGIGYsIENvbnRhaW5lciB4cyApCnsKICAgIENvbnRhaW5lciB5czsKICAgIGF1dG8gaXQgPSBzdGQ6Omluc2VydGVyKCB5cywgZW5kKCB5cyApICk7CiAgICBzdGQ6OnRyYW5zZm9ybSggYmVnaW4oIHhzICksIGVuZCggeHMgKSwgaXQsIGYgKTsKICAgIHJldHVybiB5czsKfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgUmV0LCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZS4uLiBBcmdzPgogIGF1dG8gQ3VycnkoUmV0ICgqZikoQXJnMSwgQXJncy4uLiksICBBcmcxIGFyZyApIC0+IHN0ZDo6ZnVuY3Rpb248UmV0KEFyZ3MuLi4pPgp7CiAgICByZXR1cm4gWz1dKCBBcmdzLi4uIGFyZ3MgKSB7IHJldHVybiBmKCBhcmcsIGFyZ3MuLi4gKTsgfTsKfQppbnQgbWFpbigpIAp7CglhdXRvIHNxdWFyZSA9IFtdKGludCB4KXsgcmV0dXJuIHgqeDsgfTsKCQogIHR5cGVkZWYgc3RkOjp2ZWN0b3I8aW50PiBSb3c7CiAgUm93IHJvdyA9IHsxLCAyICwgM307CiAgUm93IHNxdWFyZWRSb3cgPSBNYXAoc3F1YXJlLCByb3cpOwoKICB0eXBlZGVmIHN0ZDo6dmVjdG9yPFJvdz4gTWF0OwogIE1hdCBtYXQgPSB7ezEsMn0sezIsMyw0fX07CiAgYXV0byBzcXVhcmVFbGVtZW50cyA9IEN1cnJ5KE1hcDxSb3csIGRlY2x0eXBlKHNxdWFyZSk+LCBzcXVhcmUpOwogIE1hdCBzcXVhcmVkTWF0ID0gTWFwKHNxdWFyZUVsZW1lbnRzLCBtYXQpOwoJCglyZXR1cm4gMDsKfQ==