我在Visual Studio中摆弄,我发现了
delegate RecursiveDelegate RecursiveDelegate();
是有效的委托定义。
我没有大量的函数式编程经验,但我想知道这种模式在函数式编程中是否真的有用,或者它只是一种语义的好奇心。我想以两种方式提出这个问题:
答案 0 :(得分:1)
我有一个类似代码的例子,它不完全是一个递归委托,但它很接近。 “Y-Combinator”非常接近 - 坦率地说,我不知道它在实践中是如何工作的,但它用于定义递归函数。
以下是您需要定义的时髦代码:
public delegate T S<T>(S<T> s);
public static T U<T>(S<T> s)
{
return s(s);
}
public static Func<A, Z> Y<A, Z>(Func<Func<A, Z>, Func<A, Z>> f)
{
return U<Func<A, Z>>(r => a => f(U(r))(a));
}
现在您可以在一行中定义递归函数。
阶乘:
var fact = Y<int, int>(_ => x => x == 0 ? 1 : x * _(x - 1));
var fact5 = fact(5); // == 120
var fact6 = fact(6); // == 720
var fact7 = fact(7); // == 5040
斐波:
var fibo = Y<int, int>(_ => x => x <= 1 ? 1 : _(x - 1) + _(x - 2));
var fibo5 = fibo(5); // == 8
var fibo6 = fibo(6); // == 13
var fibo7 = fibo(7); // == 21
代码中我最喜欢的一行是来电s(s)
。说真的,如果有人能够把头脑中的那个拉直,那么他们就是天才!更不用说整个U<Func<A, Z>>(r => a => f(U(r))(a))
。