Lambda演算 - 简述Y组合子的作用
Y组合子:\f.(\x.f(xx))(\x.f(xx)),接受一个函数,返回一个高阶函数
Y组合子用于生成匿名递归函数。
什么叫匿名递归函数,考虑以下C语言递归函数
int sum(int n)
{
return n == 0 ? 0 : n + sum(n-1);
}
这个函数在内部递归调用了自身,调用自身需要函数本体的名字,这个函数叫sum,sum内部用名字sum,递归调用了自己
在lambda演算中,可以写成类似的表达式sum = \x. x == 0 ? 0 : sum x
但是对于一个lambda表达式,他本身是匿名的,lambda在定义的过程中引用了自身,就算是C++,这样的lambda表达式也是不成立的
auto sum = [](int n) {
return n == 0 ? 0 : n + sum(n-1);
};
lambda表达式本身是不具名的,我们需要绕开这个限制。
一种可能的解决办法是使用高阶函数,用另一个函数把上面的sum包装一下:它接受一个函数f,并返回一个函数,这个函数接受x,判断递归终点,或调用f继续递归:
G = \f. \x. x == 0 ? 0 : f (x-1)
写成C++是这样的
auto G = [](function<int(int)> f) {
return [&](int x) {
return x == 0 ? : 0 : x + f(x-1);
};
};
现在我们发现,当有一个函数f使得G(f) = [](int x){return x == 0 ? 0 : x + f(x-1);} = f的时候,这个f正好是我们需要的匿名递归函数sum
G(f) = f,眼熟吗,还记得不动点这个概念吗,我们需要的匿名递归函数sum就是函数G的不动点
求解这个不动点sum,我们即可获得一个匿名递归函数,如何求解见附
最后的结果:sum = YG,Y和G前面已知,这样,sum是一个签名为int(int)的函数,是一个匿名递归函数
Y组合子也称不动点组合子,用这个方法可以求解一切匿名递归函数。
附:sum = YG使得G(sum) = sum的证明:
证明:对于任意G,G(YG) = YG
令W = \x. G(xx), X = WW //这个令真的太TM绝了,反正我是没想到
有X = WW = (\x. G(xx))W = G(WW) = G(X)
又因为YG = (\x. G(xx))(\x. G(xx)) = WW = X
所以G(X) = X就是G(YG) = YG
证毕
Lambda演算 - 简述Y组合子的作用的更多相关文章
- Y组合子
Y组合子 Y组合子的用处 作者:王霄池链接:https://www.zhihu.com/question/21099081/answer/18830200来源:知乎著作权归作者所有.商业转载请联系作者 ...
- 大到可以小说的Y组合子(二)
问:上一回,你在最后曾提到"抽象性不足",这话怎么说? 答:试想,如果现在需要实现一个其它的递归(比如:Fibonacci),就必须把之前的模式从头套一遍,然后通过fib_make ...
- Racket中使用Y组合子
关于Y组合子,网上已经介绍很多了,其作用主要是解决匿名lambda的递归调用自己. 首先我们来看直观的递归lambda定义, 假设要定义阶乘的lambda表达,C#中需要这么定义 Func<in ...
- 大到可以小说的Y组合子(一)
问:上回乱扯淡了一通,这回该讲正题了吧. 答:OK. 先来列举一些我参考过,并从中受到启发的文章. (1.)老赵的一篇文章:使用Lambda表达式编写递归函数 (2.)装配脑袋的两篇文章:VS2008 ...
- 大到可以小说的Y组合子(三)
答:关于Fix的问题你fix了吗? 问:慢着,让我想想,上次留下个什么问题来着?是说我们有了一个求不动点的函数Fix,但Fix却是显式递归的,是吧? 答:有劳你还记的这个问题. 问:Fix的参与背离了 ...
- 大到可以小说的Y组合子(零)
问:啊!我想要一个匿名的递归… 答:Y(音同Why)… … … 问:作为一位命令式语言的使用者,为什么会突然折腾起Y组合子呢? 答:的确,这事儿要从很久以前的几次搁浅开始说起…上学的时候,从来没有接触 ...
- 简单易懂的程序语言入门小册子(4):基于文本替换的解释器,递归,如何构造递归函数,Y组合子
递归.哦,递归. 递归在计算机科学中的重要性不言而喻. 递归就像女人,即令人烦恼,又无法抛弃. 先上个例子,这个例子里的函数double输入一个非负整数$n$,输出$2n$. \[ {double} ...
- Haskell语言学习笔记(79)lambda演算
lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...
- [学习] 从 函数式编程 到 lambda演算 到 函数的本质 到 组合子逻辑
函数式编程 阮一峰 <函数式编程初探>,阮一峰是<黑客与画家>的译者. wiki <函数编程语言> 一本好书,<计算机程序的构造与解释>有讲到schem ...
随机推荐
- 关于变量和函数前&符号的作用
首先看一下下面的例子 <?php $a="val1"; $b="val2"; $a=&$b; echo $a."<br/>& ...
- 设置ubuntu 下git 的用户名和邮箱
设置ubuntu 下git 的用户名和邮箱 摘自 慢慢修远路,上下求索心http://yanshaozhi.iteye.com/blog/386752 虽然我没看怎么明白 但我用第一总方法就设置好了 ...
- Ubuntu 14.04中安装最新版Eclipse
Ubuntu 14.04中安装最新版Eclipse 来源:Linux社区 作者:Linux 1.安装OpenJDK Java 7 如果你的系统中没有安装Java,我们需要按照如下步骤事先安装好 ...
- Maven学习-处理资源文件
在前面两篇文章中,我们学习了Maven的基本使用方式和Maven项目的标准目录结构.接下来,我们来看下Maven是如果管理项目中的资源文件的. Java项目的资源文件,主要用于存储系统的配置信息,以及 ...
- 布隆过滤器的概述及Python实现
布隆过滤器 布隆过滤器是一种概率空间高效的数据结构.它与hashmap非常相似,用于检索一个元素是否在一个集合中.它在检索元素是否存在时,能很好地取舍空间使用率与误报比例.正是由于这个特性,它被称作概 ...
- 前端工具-Sublime、WebStorm-快捷方式使用
记录下我工作中使用的编辑软件Sublime和WebStorm用到的快捷方式来水一贴(*^__^*) Sublime是我使用的最长时间的编辑器了,也熟悉了一些快捷键使用. 1.Ctrl + / --- ...
- 各种报错各种坑 webpack让我在学习的过程中一度想要放弃
由于拓展部分不是必须的,只是可以增强用户体验,但是有些时候页面给分页预留的位置不够,这个时候我们就可以通过设置来除去这一部分 子分区由两种创建方法,一种是不定义每个子分区子分区的名字和路径由分区决定, ...
- tableView优化性能
在iOS应用中,UITableView应该是使用率最高的视图之一了.iPod.时钟.日历.备忘录.Mail.天气.照片.电话.短信. Safari.App Store.iTunes.Game Cent ...
- 初识Linux—1
1,Ctrl+C作用是终止当前的命令 2,ps显示目前正在执行的程序(命令)(process status) 3,退出是exit,连续按exit,最终会关闭终端 4,Root是管理员,其他的用户都是由 ...
- 合并果子 2004年NOIP全国联赛普及组
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆 ...