委托类型是否有用于返回与其自身相同类型的委托?

时间:2013-08-17 03:11:29

标签: c# delegates functional-programming

我在Visual Studio中摆弄,我发现了

delegate RecursiveDelegate RecursiveDelegate();

是有效的委托定义。

我没有大量的函数式编程经验,但我想知道这种模式在函数式编程中是否真的有用,或者它只是一种语义的好奇心。我想以两种方式提出这个问题:

  1. 在有副作用的情况下。我可以看到这实际上是一种在函数式语言中模拟迭代学习算法的中途方式,其中算法的实际任务作为副作用执行,并且函数的新版本是返回值。这样做了吗?
  2. 在没有副作用的情况下。我认为这原则上没用,但如果我错了,我会非常好奇。如果我们假设RecursiveDelegate()的实现没有副作用,这可能有用吗?

1 个答案:

答案 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))

相关问题