3

将方法体中定义的阶乘函数视为 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 表达式,我还可以捕获我的字典,而无需显式地将其引用传递给该方法,这非常好。

不确定我是否走在正确的轨道上...

4

1 回答 1

3

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

但是,在实践中,您可以只定义一个局部Func<..>变量,然后对其进行变异。如果你想给代表起个名字,那么它就可以正常工作(有点脏,但很简单):

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

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

于 2011-04-05T22:02:03.947 回答