您的位置:首页 > 编程语言 > C#

Recursive Lambda Expressions in C#

2009-09-10 09:52 621 查看
Code
i => new Func<Func<int,int>,Func<int,int>>(fac => x => x == 0 ? 1 : x * fac(x - 1))(new SelfApplicable<Func<Func<Func<int,int>,Func<int,int>>,Func<int,int>>>(y => f => x => f(y(y)(f))(x))(y => f => x => f(y(y)(f))(x))(fac => x => x == 0 ? 1 : x * fac(x - 1)))(i)
Neat, huh? I can’t even figure out how to line break it so that it approaches readable, so I haven’t. But! It is proof of concept that you can write real recursive lambda expressions if you really really want to! This means you can do it in expression trees, too, although I wouldn’t really recommend it.

So the next time you hear someone complain that you can’t write a recursive lambda expression, just throw them a fixed point generator!

Enough already

Of course you would like to generalize so Y and Fix don’t only work on functions over int. You can’t have generic lambdas, so what do you do? A trick is to put Y and Fix as static members of a generic class:

public class Fun<T> {
public static … Y = … ;
public static … Fix = Y(Y);
}
Then you can access the fixed point operator for int functions as Fun<int>.Fix.

For practical purposes, you can also choose to write your fixed point generator as an ordinary named generic recursive method, which is much easier and works just as well:

Func<T, T> Fix<T>(Func<Func<T,T>, Func<T,T>> F) {
return t => F(Fix(F))(t);
}
Then you also don’t need the intermediate Y combinator and the freak SelfApplicable delegate type.

Regardless of how you write your fixed point generator, it is a useful thing whenever you want to pass a recursive function that you cook up on the fly.

If you want to play some more with this stuff, I recommend the following two exercises:

1) Make a fixed point generator for functions of two arguments

2) Figure out how to make two mutually recursive functions in this way

Anyway, enough lambda calculus for one day. Now get back to work!



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: