方法:“letrec”在 C# 中(在其定义内调用 lambda 表达式)
将方法体中定义的阶乘函数视为 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 表达式,我还可以捕获我的字典,而无需显式地将其引用传递给该方法,这非常好。
但不确定我是否走在正确的轨道上......
Consider the factorial function defined within a method body as a lambda expression and assigned to a variable:
Func<int, int> factfail = n =>
{
if (n == 0)
return 1;
else
return n * factfail(n-1);
};
This fails, since factfail
isn't bound by the the local variable yet.
Is there a way to add a sort of fixpoint - by abstracting over the function itself?!
Func<Func<int, int>, int, int> fact_ = (fact, n) =>
{
if (n == 0)
return 1;
else
return n * fact(n-1);
};
fact_(??);
long story:
I need to write a recursive function that has the side effect of changing some outer state.
Therefore i am trying to write that method as a lambda expression that captures that outer state.
I am still experimenting with different styles how to write that and - besides of that one dictionary that needs to be the same for all recursive calls - i want to be as purely functional and lazy as possible.
So i was playing with LINQ, since it helps me reducing mutual data.
It also helps with understanding which parts of the code can be expressed in a functional style.
To be brief in the LINQ statement it is helpful to be able to define some helper functions in front of and i did that by binding lambda expressions to variables.
And with lamda expression i also can capture my dictionary without the need to pass its reference to the method explicitely, which is quite nice.
not sure if i am on the right track though...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以在 这篇博文,作者:Mads Torgersen。他展示了如何定义通常的定点组合器。他使用阶乘函数作为示例,因此您可以在那里找到确切的样本:-)。
然而,在实践中,您可以只定义一个本地
Func<..>
变量,然后对其进行变异。如果你想给委托一个名字,那么它就可以正常工作(它有点脏,但很简单):这是有效的,因为闭包捕获了对
fact
变量的引用,所以当你实际上调用它(在递归调用期间),该值不再是null
,而是引用委托。You can find more information about recursive lambda expressions in this blog post by Mads Torgersen. He shows how to define the usual fixed point combinator. He uses factorial function as an example, so you can find your exact sample there :-).
However, in practice, you can just define a local
Func<..>
variable and then mutate it. If you want to give a name to the delegate, then it works just fine (it is a bit dirty, but simple):This works, because the closure captures reference to the
fact
variable, so when you actually call it (during the recursive call), the value is notnull
anymore, but references the delegate.