Правильное приготовление карри на языке Си#
Вопрос
Дан метод DoSomething
это принимает функцию (без параметров) и каким-то образом обрабатывает ее.Есть ли лучший способ создать "перегрузки" для функций с параметрами, чем приведенный ниже фрагмент?
public static TResult DoSomething<TResult>(Func<TResult> func)
{
//call func() and do something else
}
public static TResult DoSomething<T0, TResult>(
Func<T0, TResult> func,
T0 arg0)
{
return DoSomething(() => func(arg0));
}
public static TResult DoSomething<T0, T1, TResult>(
Func<T0, T1, TResult> func,
T0 arg0, T1 arg1)
{
return DoSomething(arg => func(arg, arg1), arg0);
}
public static TResult DoSomething<T0, T1, T2, TResult>(
Func<T0, T1, T2, TResult> func,
T0 arg0, T1 arg1, T2 arg2)
{
return DoSomething(arg => func(arg, arg1, arg2), arg0);
}
Решение
Редактировать:Как отмечалось в комментариях, это частичное применение, а не каррирование.Я написал запись в блоге о моем понимании разницы, что людям может показаться интересным.
Ну, это не особо отличается, но я бы отделил часть каррирования от части "вызов doSomething":
public static Func<TResult> Apply<TResult, TArg> (Func<TArg, TResult> func, TArg arg)
{
return () => func(arg);
}
public static Func<TResult> Apply<TResult, TArg1, TArg2> (Func<TArg1, TArg2, TResult> func,
TArg1 arg1, TArg2 arg2)
{
return () => func(arg1, arg2);
}
// etc
Тогда:
DoSomething(Apply(foo, 1));
Таким образом, вы можете повторно использовать код карринга в других ситуациях, включая случаи, когда вы не хотите немедленно вызывать вновь возвращенный делегат.(Например, позже вы можете захотеть приготовить из него больше карри.)
Не связан с StackOverflow