## 使用 Lambda 表达式编写递归四：实现 Θ 组合子

2013-04-10 20:33 by 鹤冲天, ... 阅读, ... 评论, 收藏, 编辑
《Fish and Scales》      作者：埃舍尔

• 参数为 int；
• 返回值为 long。

# Θ 组合子

Θ 组合子也是一个常见不动点组合子，由 阿兰·图灵 发现，也称为图灵不动点组合子:

 1 Θ = (λx.λy.(y(x x y))) (λx.λy.(y(x x y)))

 1 Θv = (λx.λy.(y(λz. x x y z))) (λx.λy.(y(λz. x x y z)))

 1 Θ = (λx.λy.λn.(y(x x y) n)) (λx.λy.λn.(y(x x y) n))

 1 h = λx.λy.λn.(y(x x y)n)

 1 Θ = h h  Θ = h(h)

# 实现 h

## 确定 h 的类型

h 可调用自身 h(h)，需要用到 上一篇文章 用的 SelfApplicable<TResult>委托：

 1 delgate TResult SelfApplicable(SelfApplicable self);

h 的类型为：SelfApplicable<Func<Func<Func<int, long>, Func<int, long>>, Func<int, long>>>。

## 实现 h

 1 2 h = λx.λy.λn.(y(x x y)n) h = λx.λy.λn.(y(x(x)(y))(n)

 1 SelfApplicable, Func>, Func>> h = x => y => n => y(x(x)(y))(n);

# 实现 Θ

 1 Θ = h(h)

 1 Func, Func>, Func> Θ = h(h);

 1 2 SelfApplicable, Func>, Func>> h = x => y => n => y(x(x)(y))(n); Func, Func>, Func> Θ = h(h);

 1 2 var factorial = Θ(f => x => x == 0 ? 1 : x * f(x - 1)); var result = factorial(5); // 120

# 封装 Θ

 1 2 3 4 5 6 7 8 9 10 public class ThetaCombinator { public static Func Fix(Func, Func> f) { return Theta.Fix(f); } static class Theta { delegate T SelfApplicable(SelfApplicable self); static readonly SelfApplicable, Func>, Func>> h = x => y => n => y(x(x)(y))(n); public static readonly Func, Func>, Func> Fix = h(h); } }

 1 2 3 4 5 var factorial = ThetaCombinator.Fix(f => n => n == 0 ? 1 : n * f(n - 1)); var result1 = factorial(5); // 120 var fibonacci = ThetaCombinator.Fix(f => n => n < 2 ? n : f(n - 1) + f(n - 2)); var result2 = fibonacci(5); // 5

# 后记

 1 2 3 Func Fix(Func, Func> F) { return t => F(Fix(F))(t); }

 1 Func Fix(Func, Func> f) { return t => f(Fix(f))(t); }