Лямбда C# - варианты использования карри

Вы ищете что-то подобное

document.getElementById("DiacriticsButton").innerHTML = '<button id="mybtn">"some text"</button>';

Также возможно добавить элемент, подобный этому

var btn = document.createElement("button");
btn.innerHTML = "some text";
document.getElementById("DiacriticsButton").appendChild(btn);

12
задан Adrian Zanescu 6 February 2009 в 13:05
поделиться

5 ответов

Его более легкое для первого рассмотрения fn (x, y, z). Это могло использованием с приправой карри fn (x, y) предоставление Вам функция, которая только берет один параметр, z. Независимо от того, что потребности, которые будут сделаны с одними только X и Y, могут быть сделаны и сохранены закрытием, за которое держится возвращенная функция.

Теперь Вы несколько раз вызываете возвращенную функцию с различными значениями для z, не имея необходимость повторно вычислять часть необходимые X и Y.

Править:

Существует эффективно две причины приправить карри.


Сокращение параметра

Как Cameron говорит для преобразования функции, которая берет, говорят, что 2 параметра в функцию, которая только берет 1. Результат вызывания этой функции с приправой карри с параметром совпадает с вызовом оригинала с этими 2 параметрами.

С Лямбдами, существующими в C#, это ограничило значение, так как они могут обеспечить этот эффект так или иначе. Хотя это, Вы - C# 2 использования затем функция Карри в Вашем вопросе, имеет намного большее значение.

Подготовка вычисления

Другая причина приправить карри состоит в том, как я заявил ранее. Позволить сложным/дорогим операциям быть подготовленными и снова использоваться несколько раз, когда заключительный параметр (параметры) предоставляются функции с приправой карри.

Этот тип приправления карри не истинно возможен в C#, это действительно берет функциональный язык, который может исходно приправить любую карри из его функций для достигания.


Заключение

Сокращение параметра через Карри, которое Вы упоминаете, полезно в C# 2, но значительно обесценено в C# 3 из-за Лямбд.

12
ответ дан 2 December 2019 в 05:16
поделиться

Приправление карри используется для преобразования функции с x параметрами к функции с y параметрами, таким образом, оно может быть передано другой функции, для которой нужна функция с y параметрами.

Например, Enumerable.Select(this IEnumerable<T> source, Func<TSource, bool> selector) берет функцию с 1 параметром. Math.Round(double, int) функция, которая имеет 2 параметра.

Вы могли использовать приправление карри, чтобы "сохранить" Round функционируйте как данные и затем передайте ту функцию с приправой карри Select как так

Func<double, int, double> roundFunc = (n, p) => Math.Round(n, p);
Func<double, double> roundToTwoPlaces = roundFunc.Curry()(2);
var roundedResults = numberList.Select(roundToTwoPlaces);

Проблема здесь состоит в том, что существуют также анонимные делегаты, которые делают приправление карри избыточным. На самом деле анонимные делегаты являются формой приправления карри.

Func<double, double> roundToTwoPlaces = n => Math.Round(n, 2);
var roundedResults = numberList.Select(roundToTwoPlaces);

Или даже просто

var roundedResults = numberList.Select(n => Math.Round(n, 2));

Приправление карри было способом решить конкретную проблему, учитывая синтаксис определенных функциональных языков. С анонимными делегатами и оператором лямбды синтаксис в.NET намного более прост.

18
ответ дан 2 December 2019 в 05:16
поделиться

В некотором смысле воркование является техникой для включения автоматического частичного приложения.

Более официально приправление карри является техникой для превращения функции в функцию, которая принимает один и только один аргумент.

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

от потока в codingforums

Мне особенно нравятся объяснение и длина, в которой это объяснено на этой странице.

0
ответ дан 2 December 2019 в 05:16
поделиться

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

    void ArchiveAndUpdate(string[] files)
    {
        Func<string, bool> archiveCurry1 = (file) =>
            Archive1(file, "archiveDir", 30, 20000000, new[] { ".tmp", ".log" });

        Func<string, bool> archiveCurry2 = (file) =>
            Archive2("netoworkServer", "admin", "nimda", new FileInfo(file));

        Func<string, bool> archvieCurry3 = (file) => true;

        // backup locally before updating
        UpdateFiles(files, archiveCurry1);

        // OR backup to network before updating
        UpdateFiles(files, archiveCurry2);

        // OR do nothing before updating
        UpdateFiles(files, archvieCurry3);
    }

    void UpdateFiles(string[] files, Func<string, bool> archiveCurry)
    {
        foreach (var file in files)
        {
            if (archiveCurry(file))
            {
                // update file //
            }
        }
    }

    bool Archive1(string fileName, string archiveDir, 
        int maxAgeInDays, long maxSize, string[] excludedTypes)
    {
        // backup to local disk
        return true;
    }

    bool Archive2(string sereverName, string username, 
        string password, FileInfo fileToArchvie)
    {
        // backup to network
        return true;
    }
-1
ответ дан 2 December 2019 в 05:16
поделиться

Один пример: у Вас есть функция compare(criteria1, criteria2, option1, option2, left, right). Но когда Вы хотите предоставить функцию compare к некоторому методу с видами список, затем compare() должен только взять два аргумента, compare(left, right). С карри Вы затем связываете аргументы критериев, поскольку Вам нужно оно для сортировки этого списка, и затем наконец эта высоконастраиваемая функция представляет алгоритму сортировки как любая другая плоскость compare(left,right).

Деталь: делегаты.NET используют неявное приправление карри. Каждая нестатическая функция членства класса имеет неявное this ссылка, тем не менее, когда Вы пишете делегатам, Вы не должны вручную использовать некоторых приправляющих карри для привязки this к функции. Вместо этого C# заботится о синтаксическом сахаре, автоматически связывает это и возвращает функцию, которая только требует оставленных аргументов.

В повышении C++:: свяжите и др. используются для того же. И как всегда, в C++ все явно (например, если Вы хотите передать функцию члена экземпляра как обратный вызов, необходимо явно связать this).

0
ответ дан 2 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: