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组合子的作用的更多相关文章

  1. Y组合子

    Y组合子 Y组合子的用处 作者:王霄池链接:https://www.zhihu.com/question/21099081/answer/18830200来源:知乎著作权归作者所有.商业转载请联系作者 ...

  2. 大到可以小说的Y组合子(二)

    问:上一回,你在最后曾提到"抽象性不足",这话怎么说? 答:试想,如果现在需要实现一个其它的递归(比如:Fibonacci),就必须把之前的模式从头套一遍,然后通过fib_make ...

  3. Racket中使用Y组合子

    关于Y组合子,网上已经介绍很多了,其作用主要是解决匿名lambda的递归调用自己. 首先我们来看直观的递归lambda定义, 假设要定义阶乘的lambda表达,C#中需要这么定义 Func<in ...

  4. 大到可以小说的Y组合子(一)

    问:上回乱扯淡了一通,这回该讲正题了吧. 答:OK. 先来列举一些我参考过,并从中受到启发的文章. (1.)老赵的一篇文章:使用Lambda表达式编写递归函数 (2.)装配脑袋的两篇文章:VS2008 ...

  5. 大到可以小说的Y组合子(三)

    答:关于Fix的问题你fix了吗? 问:慢着,让我想想,上次留下个什么问题来着?是说我们有了一个求不动点的函数Fix,但Fix却是显式递归的,是吧? 答:有劳你还记的这个问题. 问:Fix的参与背离了 ...

  6. 大到可以小说的Y组合子(零)

    问:啊!我想要一个匿名的递归… 答:Y(音同Why)… … … 问:作为一位命令式语言的使用者,为什么会突然折腾起Y组合子呢? 答:的确,这事儿要从很久以前的几次搁浅开始说起…上学的时候,从来没有接触 ...

  7. 简单易懂的程序语言入门小册子(4):基于文本替换的解释器,递归,如何构造递归函数,Y组合子

    递归.哦,递归. 递归在计算机科学中的重要性不言而喻. 递归就像女人,即令人烦恼,又无法抛弃. 先上个例子,这个例子里的函数double输入一个非负整数$n$,输出$2n$. \[ {double} ...

  8. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  9. [学习] 从 函数式编程 到 lambda演算 到 函数的本质 到 组合子逻辑

    函数式编程 阮一峰 <函数式编程初探>,阮一峰是<黑客与画家>的译者. wiki <函数编程语言> 一本好书,<计算机程序的构造与解释>有讲到schem ...

随机推荐

  1. (转) PowerDesigner中Table视图同时显示Code和Name

    PowerDesigner中Table视图同时显示Code和Name,像下图这样的效果: 实现方法:Tools-Display Preference

  2. BP神经网络

    秋招刚结束,这俩月没事就学习下斯坦福大学公开课,想学习一下深度学习(这年头不会DL,都不敢说自己懂机器学习),目前学到了神经网络部分,学习起来有点吃力,把之前学的BP(back-progagation ...

  3. linux压缩解压文件

    首先进入文件夹 cd /home/ftp2/1520/web 压缩方法一:压缩web下的888.com网站 zip -r 888.com.zip888.com 压缩方法二:将当前目录下的所有文件和文件 ...

  4. 2016年中国大学生程序设计竞赛(合肥)-重现赛1001 HDU 5961

    传递 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  5. 数据库SQL优化总结

    1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  6. Objective-C数据类型之id,SEL,BOOL,nil,NULL和NSNull

     id id是指向Objective-C对象的指针,等价于C语言中的void*,可以映射任何对象指针指向他,或者映射它指向其他的对象.常见的id类型就是类的delegate属性. SEL SEL类型是 ...

  7. NewQuant的设计(二)——MatrixComputation的领域分析

    NewQuant的设计——MatrixComputation的领域分析 MatrixComputation是NewQuant中最重要也是最大的一个模块,这个模块的领域分析要从回答几个问题开始. 一.矩 ...

  8. 3数字cn域名延续数字域名火爆行情! 珍品域名 593.cn 出售

      近日, 域名投资者小维放出珍藏多年的珍品域名593.cn, 据悉该域名将参加易名中国举办的数字域名专场拍卖活动,将以1元标价起拍.   域名593.cn,数字“593”谐音“我就上.吾就上.我就商 ...

  9. Django值Cookie基础

    一.什么是Cookie? Cookies就是服务器暂时存放在你的电脑里的资料(.txt格式的文本文件),好让服务器用来辨认你的计算机.当你在浏览网站的时候,Web服务器会先送一小小资料放在你的计算机上 ...

  10. HttpClientUtil [使用apache httpclient模拟http请求]

    基于httpclient-4.5.2 模拟http请求 以get/post方式发送json请求,并获取服务器返回的json -------------------------------------- ...