博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 Lambda 表达式编写递归四:实现 Θ 组合子
阅读量:7292 次
发布时间:2019-06-30

本文共 2348 字,大约阅读时间需要 7 分钟。

Fish and Scales
《Fish and Scales》      作者:埃舍尔

本系列文章目录:

 

我们实现 Y 组合子,这篇文章讨论 Θ 组合子的实现。(Θ 读 Theta,希腊语第八个字母,小写为 θ。)

继续使用前文中的类型假定,假定递归函数:

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

Θ 组合子

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

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

传值调用形式为((x x y) η-展开为 λz. x x y z):

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

不过我还是喜欢把 y (x x y) η-展开为: λn.(y (x x y) n),得出:

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

定义一个中间变量 h,令:

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

则:

1
Θ = h h
Θ = h(h)

实现 h

确定 h 的类型

根据的推断,Θ 的类型为 Func<Func<Func<int, long>, Func<int, long>>, Func<int, long>> , 这也是 h 返回值的类型。

h 可调用自身 h(h),需要用到 用的 SelfApplicable<TResult>委托:

1
delgate TResult 
(
self);

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

实现 h

对 h 作一步简单变换:

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

使用总结出的规律,可写出:

1
<<<<, >, <, >>, <, >>> h = x => y => n => y(x(x)(y))(n);

实现 Θ

根据 Θ 的简单式:

1
Θ = h(h)

可写出:

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

与 h 的代码放在一块:

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

还记得 最后给出的代吗?(出处:)

比较下,看看是不是一回事的。

调用下试试:

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

封装 Θ

12345678910
public class  {    public static 
Fix
(<
,
> f) { return
.Fix(f); } static class
{ delegate T
(
self); static readonly <<<
,
>,
>> h = x => y => n => y(x(x)(y))(n); public static readonly <<
,
>,
> Fix = h(h); }}

调用示例代码:

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

后记

文中也给出了下面一种简单到极致的写法:

123
Fix
(<
,
> F) { return t => F(Fix(F))(t);}

增加一个泛型参数并修改下参数的名称,得出:

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

便是 给出的写法。 中将说明这个是如何编导出的。

转载地址:http://xqrjm.baihongyu.com/

你可能感兴趣的文章
django 基础进 COOKIE
查看>>
[Java 8] (10) 使用Lambda完成函数组合,Map-Reduce以及并行化
查看>>
@EnableWebMvc
查看>>
eclipse中输入的中文为繁体的问题
查看>>
.NET跨平台:在Linux Ubuntu上编译coreclr/corefx/dnx(20150617)
查看>>
[CQOI2016]手机号码
查看>>
Eclipse CDT 配置C /C ++ 标准库 (UBUNTU 12 )
查看>>
面霸吕国栋之:整理的一些面试题
查看>>
转 Python爬虫入门五之URLError异常处理
查看>>
转 Python执行系统命令的方法
查看>>
CSS 折角效果
查看>>
个人作业3---个人总结
查看>>
[分享]ip地址爬取过滤的shell
查看>>
差分数组
查看>>
Shiro 加密helloWorld
查看>>
关于安装sql2012出现的netfx3功能问题
查看>>
基础关3
查看>>
tar 解压缩
查看>>
(转)Sharepoint学习笔记—Debug--寻找 WSS_Logging下的ULSTraceLog
查看>>
数据库命令大全(也不是很全哈)
查看>>