рддреЛ, рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ (рдФрд░ рдордЬрд╛ рд╣рдорд╛рд░реЗ рд╕рд╛рде рдЖ рд╕рдХрддрд╛ рд╣реИ)ред рд╕реНрд▓рд╛рдЗрдбреНрд╕рд╢реЗрдпрд░ рдкрд░ рд╕реНрд▓рд╛рдЗрдб рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╣ рдкрд╛рда рднреА рдЙрдкрд▓рдмреНрдз рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓реЗрдЦрдХ JSON рдирд┐рд░реНрдорд╛рддрд╛ рдбрдЧрд▓рд╕ рдХреНрд░реЙрдХрдлреЛрд░реНрдб рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдереЗред
рдПрдХ рдкрд╣рдЪрд╛рди рд╕рдорд╛рд░реЛрд╣ рдЬреЛ рдПрдХ рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╣реА рддрд░реНрдХ рджреЗрддрд╛ рд╣реИ:
auto Identity = [](auto x) { return x; }; Identity(3); // 3
рдЕрдиреБрд╡рд╛рджрдХ рдХрд╛ рдиреЛрдЯ : C ++ 11 рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдирдпрд╛ рдЯрд╛рдЗрдк рдирд╛рдореЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред
рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЙрдк рдФрд░ рдореБрд▓, рдЬреЛ рджреЛ рддрд░реНрдХ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдХреНрд░рдорд╢рдГ рдЙрдирдХрд╛ рдпреЛрдЧ, рдЕрдВрддрд░ рдФрд░ рдЙрддреНрдкрд╛рдж рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ:
auto add = [](auto x, auto y) { return x + y; }; auto sub = [](auto x, auto y) { return x - y; }; auto mul = [](auto x, auto y) { return x * y; };
рдкрд╣рдЪрд╛рди рдлрд╝рдВрдХреНрд╢рди, рдЬреЛ рдПрдХ рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЖрдВрддрд░рд┐рдХ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реИ, рдЬрдм рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдореВрд▓ рддрд░реНрдХ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛:
auto identityf = [](auto x) { class Inner { int x; public: Inner(int i): x(i) {} int operator() () { return x; } }; return Inner(x); }; identityf(5)(); // 5
рдПрдХ рдФрд░ рдкрд╣рдЪрд╛рди рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЬреЛ рдПрдХ рд╡рд╕реНрддреБ рдирд╣реАрдВ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдлрд╝рдВрдХреНрд╢рди (рд╣рд╛рдБ, рдЕрдм рдЖрдк рдлрд╝рдВрдХреНрд╢рди рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ):
auto identityf = [](auto x) { return [=]() { return x; }; }; identityf(5)(); // 5
рдиреЛрдЯ: рд▓рдВрдмреЛрджрд░ рдХрд╛рд░реНрдп functions рдмрдВрдж:
- рд▓реИрдВрдмрдбрд╛ рд╕рд┐рд░реНрдл рдПрдХ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рд╣реИред
- рдПрдХ рдХреНрд▓реЛрдЬрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдЙрд╕ рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреА рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рдореЗрдВ, рд╕рдорд╛рди рдЪрд┐рд╣реНрди "рд╕рдВрджрд░реНрдн рдкрд░ рдХрдмреНрдЬрд╛" рджрд░реНрд╢рд╛рддрд╛ рд╣реИред
- рд╕рднреА рд▓реИрдореНрдмрдбрд╛ рдХреНрд▓реЛрдЬрд░ рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рди рд╣реА рд╕рднреА рд▓реИрдореНрдмрдбреНрд╕ рд▓реИрдореНрдмрдбрд╛ рд╣реИрдВред
- C ++ рдореЗрдВ рдХреНрд▓реЛрдЬрд░ рд╕рд╛рдорд╛рдиреНрдп рд╡рд╕реНрддреБрдПрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
- рдХреНрд▓реЛрдЬрд░ рдЙрди рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЬреАрд╡рди рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╡реЗ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╕рд╛рдЭрд╛ рдХрд░реЗрдВ_рдкреНрд░рд╛рдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ)ред
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдЬрдирд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдЕрдВрддрд░рд╛рд▓ рд╕реЗ рдирдВрдмрд░ рджреЗрддрд╛ рд╣реИ:
auto fromto = [](auto start, auto finish) { return [=]() mutable { if(start < finish) return start++; else throw std::runtime_error("Complete"); }; }; auto range = fromto(0, 10); range(); // 0 range(); // 1
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдПрдХ рдирдВрдмрд░ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ:
auto addf = [](auto x) { return [=](auto y) { return x+y; }; }; addf(5)(4); // 9
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рджреВрд╕рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ рд╕реНрд╡реИрдк рдХрд░рддрд╛ рд╣реИ:
auto swap =[](auto binary) { return [=](auto x, auto y) { return binary(y, x); }; }; swap(sub)(3, 2); // -1
рдПрдХ рдмрд╛рдЗрдирд░реА рдлрд╝рдВрдХреНрд╢рди рд▓реЗрддрд╛ рд╣реИ рдФрд░ рджреЛ рдмрд╛рд░ рдмрд╛рдЗрдирд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реНрдХ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдХрд┐ рдПрдХ unary рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ:
auto twice =[](auto binary) { return [=](auto x) { return binary(x, x); }; }; twice(add)(11); // 22
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдмрд╛рдЗрдирд░реА рдлрд╝рдВрдХреНрд╢рди рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рджреЛ рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ:
auto applyf = [](auto binary) { return [=](auto x) { return [=](auto y) { return binary(x, y); }; }; }; applyf(mul)(3)(4); // 12
рдПрдХ рдХрд░реА рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдмрд╛рдЗрдирд░реА рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдПрдХ рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬреЛ рджреВрд╕рд░рд╛ рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ:
auto curry = [](auto binary, auto x) { return [=](auto y) { return binary(x, y); }; }; curry(mul, 3)(4); // 12
рдиреЛрдЯ: рдХрд░реА (schrying, sch├╢nfinkeling) рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ рдЬреЛ рдХрдИ рддрд░реНрдХреЛрдВ рдХреЛ рдПрдХ рддрд░реНрдХ рд▓реЗрдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред
- рдПрдХ ╬╗-рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ, рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓ рдПрдХ рддрд░реНрдХ рд▓реЗрддреЗ рд╣реИрдВред
- рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рд╣рд╛рд╕реНрдХреЗрд▓ рд╕реАрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реА рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИред
- рдХрд░реА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдПрдХ рдЖрдВрд╢рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИред
рд╕рдорд╛рд░реЛрд╣ рдХрд╛ рдЖрдВрд╢рд┐рдХ рдЙрдкрдпреЛрдЧ:
auto addFour = [](auto a, auto b, auto c, auto d) { return a+b+c+d; }; auto partial = [](auto func, auto a, auto b) { return [=](auto c, auto d) { return func(a, b, c, d); }; }; partial(addFour,1,2)(3,4); //10
рддреАрди рд╡рд┐рдХрд▓реНрдк, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдЬреЛ рдПрдХ рдирдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдП рдмрд┐рдирд╛ рддрд░реНрдХ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ:
auto inc = curry(add, 1); auto inc = addf(1); auto inc = applyf(add)(1);
рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
auto composeu =[](auto f1, auto f2) { return [=](auto x) { return f2(f1(x)); }; }; composeu(inc1, curry(mul, 5))(3) // (3 + 1) * 5 = 20
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдмрд╛рдЗрдирд░реА рдлрд╝рдВрдХреНрд╢рди рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдХрд╣рд╛ рдЬрд╛ рд╕рдХреЗ:
auto once = [](auto binary) { bool done = false; return [=](auto x, auto y) mutable { if(!done) { done = true; return binary(x, y); } else throw std::runtime_error("once!"); }; }; once(add)(3,4); // 7
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдмрд╛рдЗрдирд░реА рдлрд╝рдВрдХреНрд╢рди рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬреЛ рджреЛ рддрд░реНрдХ рдФрд░ рдХреЙрд▓рдмреИрдХ рд▓реЗрддрд╛ рд╣реИ:
auto binaryc = [](auto binary) { return [=](auto x, auto y, auto callbk) { return callbk(binary(x,y)); }; }; binaryc(mul)(5, 6, inc) // 31 binaryc(mul)(5, 6, [](int a) { return a+1; }); //
рдЕрдВрдд рдореЗрдВ, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддреАрди рдХрд╛рд░реНрдп рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
- рдЗрдХрд╛рдИ рдкрд╣рдЪрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рд╣реА рд╣реИ;
- stringify - рдЕрдкрдиреЗ рддрд░реНрдХ рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ рдФрд░ рдЙрд╕ рдкрд░ рдЗрдХрд╛рдИ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ;
- bind - рдЗрдХрд╛рдИ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬреЛ рдХреЙрд▓рдмреИрдХ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрдХрд╛рдИ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдкрд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред
auto unit = [](auto x) { return [=]() { return x; }; }; auto stringify = [](auto x) { std::stringstream ss; ss << x; return unit(ss.str()); }; auto bind = [](auto u) { return [=](auto callback) { return callback(u()); }; };
рдЕрдм рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
std::cout << "Left Identity " << stringify(15)() << "==" << bind(unit(15))(stringify)() << std::endl; std::cout << "Right Identity " << stringify(5)() << "==" << bind(stringify(5))(unit)() << std::endl;
рдЗрдХрд╛рдИ рдФрд░ рдмрд╛рдЗрдВрдб рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ? рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕рдиреНрдпрд╛рд╕реА рд╣реИ ред
рд▓реЗрдЦрдХ рдХреА рдмреНрд▓реЙрдЧ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреА рджреВрд╕рд░реА рдкреЛрд╕реНрдЯ рдкрдврд╝реЗрдВред