# 发一个lambda表达式的例子，一直没有看懂。

bluedoctor 2008-07-17 09:36:40
delegate T SelfApplicable<T>(SelfApplicable<T> self);

/// <summary>
/// Lambda 表达式 递归测试
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public int Test2(int i)
{
// Y 算子
SelfApplicable<Func<Func<Func<int, int>, Func<int, int>>, Func<int, int>>> Y = y => f => x => f(y(y)(f))(x);
// 不动点
Func<Func<Func<int, int>, Func<int, int>>, Func<int, int>> Fix = Y(Y);
// 高阶函数定义
Func<Func<int, int>, Func<int, int>> F = fac => x => x == 0 ? 1 : x * fac(x - 1);
// 阶乘函数
Func<int, int> factorial = Fix(F);
int r = factorial(i);
Console.WriteLine("{0}的阶乘={1}",i,r);
return r;

}
---------------

...全文
125 6 打赏 收藏 转发到动态 举报

6 条回复

bluedoctor 2008-07-18
• 打赏
• 举报

• 打赏
• 举报

Y组合子，因为labmda是匿名的，所以要做递归的时候需要利用Y组合子来实现。建议看相关数学理论证明
zhenghaibingood 2008-07-17
• 打赏
• 举报

<Func <Func <Func <int, int>, Func <int, int>>, Func <int, int>>>

nattystyle 2008-07-17
• 打赏
• 举报

d
zhi11ming 2008-07-17
• 打赏
• 举报

c# 3.0新特性，我也没弄明白
vwxyzh 2008-07-17
• 打赏
• 举报

So how does this work again?

It is instructive to look at function evaluation as a gradual in-place replacement of terms with what they evaluate to. In fact that is how the semantics of the lambda calculus are typically described. So let’s go ahead and “execute” the program ourselves, to observe how the recursion comes about.

First, Y is a lambda expression, so there’s nothing to execute (well in C# a delegate is generated and stored, but that’s it).

Y = y => f => x => f(y(y)(f))(x)

Next, what happens when we build the Fix function? Let’s evaluate:

Fix = Y(Y) = f => x => f(Y(Y)(f))(x)

The higher order function F is again a lambda so nothing to evaluate:

F = fac => x => x == 0 ? 1 : x * fac(x-1)

In the following we will allow ourselves to use the local variable names above as abbreviations of the functions themselves. Now we are ready to build our factorial function:

factorial = Fix(F) = x => F(Y(Y)(F))(x)

Now let’s apply factorial to a value:

factorial(5)
= F(Y(Y)(F))(5)
= (x => x == 0 ? 1 : x * Y(Y)(F)(x-1))(5)
= 5 == 0 ? 1 : 5 * Y(Y)(F)(5 – 1)
= 5 * Y(Y)(F)(4)
= 5 * (y => f => x => f(y(y)(f))(x))(Y)(F)(4))
= 5 * F(Y(Y)(F))(4)

See how the recursion occurs? The third-to-last line is equivalent to 5 * Fix(F)(4). So we take the fixed point of F once again, so that the last line is equivalent to 5 * factorial(4)! The factorial function has completed its self replication and is ready to party on the next argument. Of course it will go around and around from here, and all we need to see is how it ends. At some point we’ll get to:

5 * 4 * 3 * 2 * 1 * F(Y(Y)(F))(0)
= 5 * 4 * 3 * 2 * 1 * (x => x == 0 ? 1 : x * Y(Y)(F)(x-1))(0)
= 5 * 4 * 3 * 2 * 1 * 0 == 0 ? 1 : 0 * Y(Y)(F)(0 – 1)
= 5 * 4 * 3 * 2 * 1 * 1
= 120

Magic! We’re done.

110,620

• 近7日
• 近30日
• 至今