определение опровергает первоначальную цель Y-комбинатора, поскольку оно опирается на присущую C # поддержку определения рекурсивных функций. Тем не менее, он по-прежнему полезен тем, что позволяет определять анонимные рекурсивные функции в C #.
леднее время я провел некоторое время, оборачиваясь вокруг комбинатора Y, и обнаружил, что он обычно определяется (более или менее) следующим образом (это в C #, но язык выбора не важен):
public delegate TResult SelfApplicable<TResult>(SelfApplicable<TResult> r);
public static TResult U<TResult>(SelfApplicable<TResult> r)
{
return r(r);
}
public static Func<TArg1, TReturn> Y<TArg1, TReturn>(Func<Func<TArg1, TReturn>, Func<TArg1, TReturn>> f)
{
return U<Func<TArg1, TReturn>>(r => arg1 => f(U(r))(arg1));
}
Хотя это совершенно функционально (каламбур), кажется, что мое определение намного проще:
public static Func<TArg1, TReturn> Y<TArg1, TReturn>(Func<Func<TArg1, TReturn>, Func<TArg1, TReturn>> f)
{
return f(n => Y(f)(n));
}
Есть ли причина, по которой последнее определение не столь распространено (я еще не нашел его в сети)? Возможно, это как-то связано с определением Y в терминах самого себя?