考虑在方法主体中定义为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/