考虑在方法主体中定义为lambda表达式并分配给变量的阶乘函数:

Func<int, int> factfail = n =>
{
    if (n == 0)
        return 1;
    else
        return n * factfail(n-1);
};


这失败了,因为factfail尚未被本地变量绑定。

有没有一种方法可以添加某种定点-通过对函数本身进行抽象?

Func<Func<int, int>, int, int> fact_ = (fact, n) =>
{
    if (n == 0)
        return 1;
    else
        return n * fact(n-1);
};

fact_(??);


很长的故事:
我需要编写一个具有更改某些外部状态的副作用的递归函数。
因此,我试图将该方法编写为捕获外部状态的lambda表达式。

我仍在尝试使用不同的样式编写该代码,并且-除了该字典对于所有递归调用都必须相同之外-我希望尽可能地纯函数化和惰性化。

所以我在玩LINQ,因为它可以帮助我减少相互数据。
它还有助于理解可以用功能样式表示代码的哪些部分。

简而言之,在LINQ语句中,能够在其前面定义一些帮助器函数很有帮助,而我通过将lambda表达式绑定到变量来做到这一点。

使用lamda表达式,我也可以捕获我的字典,而无需显式地将其引用传递给该方法,这非常好。

虽然不确定我是否走对了...

最佳答案

您可以在Mads Torgersen的this blog post中找到有关递归lambda表达式的更多信息。他展示了如何定义通常的定点组合器。他以阶乘函数为例,因此您可以在此处找到您的确切样本:-)。

但是,实际上,您可以只定义一个局部Func<..>变量,然后对其进行突变。如果您想给委托人起个名字,那么它就可以正常工作(有点脏,但是很简单):

Func<int, int> fact = null;
fact = (n) => (n == 0) ? 1 : n * fact(n-1);


这是可行的,因为闭包捕获对fact变量的引用,因此当您实际调用它(在递归调用期间)时,该值不再是null,而是引用了委托。

关于c# - 作法:在C#中使用“letrec”(其定义内的lambda表达式调用),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5559077/

10-10 19:45