Подтвердить что ты не робот

Что это за конструкция С++ 14, которая, кажется, цепочка лямбда?

Это следующий вопрос по этому вопросу: Lambda-Over-Lambda в С++ 14, где ответы объясняют код.

Это о лямбда, которая создает другую лямбда, которая при вызове вызывает прошедшую лямбду и передает возвращаемое значение в исходную лямбду, возвращая тем самым новый экземпляр второй лямбда.

В этом примере показано, как можно привязать лямбды.

Скопируйте исходный вопрос:

#include <cstdio>

auto terminal = [](auto term)            // <---------+  
{                                        //           |
    return [=] (auto func)               //           |  ???
    {                                    //           |
        return terminal(func(term));     // >---------+
    };
};


auto main() -> int
{
    auto hello =[](auto s){ fprintf(s,"Hello\n"); return s; };
    auto world =[](auto s){ fprintf(s,"World\n"); return s; };


    terminal(stdout)
            (hello)
            (world) ;

    return 0;

}

Есть ли уже имя для этой конструкции, а если нет, то что она должна быть вызвана? Он похож на конструкции на других языках?

Примечание. Меня не интересует, действительно ли это полезно.

4b9b3361

Ответ 1

Я немного огляделся и выяснил, что основная функциональность - это переупорядочение вызовов функций, как описано в ответах , на исходный вопрос.

Итак, world(hello(stdout)); переписывается на terminal(stdout)(hello)(world);, который в общем случае может быть записан как compose(stdout)(hello)(world);.

Я думаю, что это полезно только при достойном частичном приложении, которое lambdas предоставляет немного, поэтому мы могли бы иметь compose(4)([](int x){ return x + 7; })([](int x){ return x * 2; })([](int x){ return x == 22; });, который должен возвращать true, если мои вычисления (и слепое кодирование) являются хорошими.

или подчеркнуть частичное применение:

auto add7 = [](int x){ return x + 7; };
auto dbl = [](int x){ return x * 2; };
auto equal22 = [](int x){ return x == 22; };
assert(compose(4)(add7)(dbl)(equals22));

1 основная проблема с этой реализацией, вероятно, заключается в том, что результат не может быть оценен, потому что в конце возвращается лямбда, поэтому конструкция в этом ответе может быть лучше подходит (функция разделяется запятой, а не скобкой).

Ответ 2

terminal(x) возвращает аппликатор, который метод-цепочки его возвращаемое значение в terminal для повторного вызова.

Но мы могли бы обобщить его.

Предположим, что у вас есть функция F. F принимает аргумент и заносит его в стек.

Затем он проверяет стек. Если верхняя часть стека, оцененная на некотором подмножестве стека, будет работать для вызова, она делает это и возвращает результат обратно в стек. В общем случае такой вызов может возвращать кортеж результатов.

Итак:

F(3)(2)(add)(2)(subtract)(7)(3)(multiply)(power)

будет оценивать:

((3+2)-2)^(7*3)

Ваш terminal делает это с 0 функциями аргументов (первый аргумент) и с 1 функцией аргументов (каждый аргумент после этого) и поддерживает только 1 возвращаемое значение для каждого вызова.

Выполнение этого с помощью лямбда было бы сложным, но то, что я описал, выполнимо в С++.

Таким образом, одно имя для него будет программироваться на основе стека.

Ответ 3

Насколько я знаю, пока нет "официального" имени.

Предложения:

  • Лямбда-цепочка
  • Колбаса лямбда
  • Карри-колбаса