Я прочитал Эта статья , и мне она показалась интересной.
Подводя итог для тех, кто не хочет читать весь пост. Автор реализует функцию более высокого порядка с именем Curry, как это (рефакторинг мной без его внутреннего класса):
public static Func<T1, Func<T2, TResult>>
Curry<T1, T2, TResult>(this Func<T1, T2, TResult> fn)
{
Func<Func<T1, T2, TResult>, Func<T1, Func<T2, TResult>>> curry =
f => x => y => f(x, y);
return curry(fn);
}
Это дает нам возможность взять выражение типа F (x, y)
например.
Func<int, int, int> add = (x, y) => x + y;
и назовите его в виде F.Curry () (x) (y);
Эту часть я поняла, и я нахожу ее классной, вызывающей. То, что я не могу обернуть мою голову, является практическими случаями для этого подхода. Когда и где необходима эта техника и что из нее можно извлечь?
Заранее спасибо.
Отредактировано:
После первых 3 ответов я понимаю, что выигрыш будет заключаться в том, что в некоторых случаях, когда мы создаем новую функцию из карри, некоторые параметры не оцениваются повторно.
Я провел небольшой тест на C # (имейте в виду, что меня интересует только реализация C #, а не теория карри в целом):
public static void Main(string[] args)
{
Func<Int, Int, string> concat = (a, b) => a.ToString() + b.ToString();
Func<Int, Func<Int, string>> concatCurry = concat.Curry();
Func<Int, string> curryConcatWith100 = (a) => concatCurry(100)(a);
Console.WriteLine(curryConcatWith100(509));
Console.WriteLine(curryConcatWith100(609));
}
public struct Int
{
public int Value {get; set;}
public override string ToString()
{
return Value.ToString();
}
public static implicit operator Int(int value)
{
return new Int { Value = value };
}
}
При 2 последовательных вызовах curryConcatWith100 оценка ToString () для значения 100 вызывается дважды (один раз для каждого вызова), поэтому я не вижу здесь никакого выигрыша в оценке. Я что-то упустил?