这个名字和什么孵化器重名。为了澄清,这里的是程序设计里面的Y-Combinator。

使用JavaScript的原因仍然是它适合常人理解,尤其是对函数式编程没有任何概念的人。

引入

在λ演算里面是没有,拥有具体名字的函数的,例如一个最简单的例子——递归求阶乘,你可能会这样写一段代码:

function fact(n)
{return n > 1 ? n * fact(n - 1) : 1;
}

我们现在把它变成λ函数版本的:

function(n)
{return n > 1 ? n * fact(n - 1) : 1;
}

那么问题就来了,fact咋办?在最开始的代码中,fact事实上就是这个被调用的函数。而第二段代码,里面可没有什么fact,而之前的调用fact,现在就变成了调用λ函数本身。但是,λ函数可没有this指针这样的东西,那怎么办嗯?

对应的故事依然存在于λ演算,没法操作一个匿名函数完成递归。这显然令人感到不愉快。

一个很好的想法是我们把这个函数作为另一个匿名函数的参数:

function(fact)
{return function(n){return n > 1 ? n * fact(n - 1) : 1;}
}

但是问题也来了,调用的时候传入的fact是什么呢?。

虚假的Y-Combinator

我们把这个函数叫做h(这样似乎失去了匿名函数的意义,但是它是一个不错的理解方式):

let h = function(fact)
{// return的这个lambda叫做greturn function(n){return n > 1 ? n * fact(n - 1) : 1;}
}

现在我们要找到一个特殊的函数Y,它能做到这个效果:Y(h) == h内层的λ函数 == g。方便起见,我们把内层的λ叫做g。

而上面的这个h,只需要h(g)即可拿到g。也就是说,h(g) == g。

这条性质类似于f(x) == x,一个函数传入参数x,得到的返回值依然是x。这个x就是函数f的不动点。当然不动点通常是个值,但是它也可以是个函数。

从h(g) == g来看,函数h的不动点就是内层的λ函数g。

那么,Y的工作就变成了拿到函数h的不动点g。这就是所谓的不动点组合子:Y-Combinator。

容易得到:Y(h) == g == h(g) == h(Y(h))。(如果没看出来:Y(h)会得到g,g是函数h的不动点,因此h(g)也得到g,再将Y(h) == g代换到h(g)得到h(Y(h)))。

这样你就能快速得到下面的代码了:

function Y(h)
{return h(Y(h));
}

这就是不严格的Y-Combinator,准确说它压根不是Y-Combinator:

我们用函数式的写法写出来,如果不熟悉下面的语法——Y(h)在下面被写成了Y h,对应的,h (Y h)的意思就是h(Y(h)),括号依然是为了表明运算优先级:

不严格的Y-Combinator懒惰求值版本: g == (Y h) == h (Y h)

试试能用吗?写一下let fact = Y(h); 看看?

可能发现不能用了:

h(Y(h))

-> h(h(Y(h)))

-> h(h(h(Y(h))))

-> h(h(h(h(Y(h)))))

...

这个递归是无法终止的。所以上面的函数是无法在JavaScript中运行的。但是如果你有一个懒惰求值的语言(这类语言通常是函数式语言),可以试试,会发现它确实能得到正确的结果。JavaScript不会懒惰求值,因此我们需要一个小技巧。

回到JavaScript的例子。因为函数g是一个带参数的函数(本文的例子是带一个参数),所以我们可以引入一个新的函数:

function(x)
{return g(x);
}

很显然这个函数是和g等价的,无论g想干什么。试一试是否如此呢?

而g可以替换成Y(h),因此:

function(x)
{return (Y(h))(x);    // 可以写成Y(h)(x), 这样看着更简洁
}

现在我们可以设计这个函数Y了:

function Y(h)
{return h(function(x){return Y(h)(x);});
}

ok~任务倒此完成一半了,试试下面的代码,是否得到了7的阶乘呢?

function Y(h)
{return h(function(x){return Y(h)(x);});
}
console.log("7! = ", Y(function(fact)
{return function(x){return x > 1 ? x * fact(x - 1) : 1;};
})(7));

我们把上面的式子变成函数式的写法:

不严格的Y-Combinator严格求值版本: g == (Y h) == (h (λx.( (Y h) x ) ) )

真正的Y-Combinator

真正的Y-Combinator是不含有自由变量的Y的,在上面的例子我们一直使用着一个在别处定义的变量Y,用Y(h)(x)来完成一个递归操作,因而不是真正的Y-Combinator。

真正的Y-Combinator是这样的:Y = λf.(λx.f (x x)) (λx.f (x x))

它能够满足Y f = f (Y f)

参考

最大的参考是The Y Combinator (Slight Return),然后还有各个大佬的文章或博客。

Y-Combinator : 实现在λ演算里面的递归相关推荐

  1. Y Combinator

    常见的例子 阶乘函数: fact = (a) -> if a > 0 then a * fact(a - 1) else 1 问题的提出 如上,在fact函数中调用了fact本身,无法使用 ...

  2. Y Combinator 创业课 2018 @北京

    为了更好地与中国的创业公司交流,硅谷创业孵化器 Y Combinator(YC)首次登陆中国,并于 5 月 19 日在清华大学举办"Startup School 北京". &quo ...

  3. 每个创始人都需要了解的来自 Y Combinator 的 13 个见解

    作者 | Jaryd Hermann 译者 | Arvin,责编 | 王晓曼 头图 | CSDN 下载自东方 IC 出品 | CSDN(ID:CSDNnews) 以下为译文: 前言 这是世界上第一大创 ...

  4. Y Combinator Is Boot Camp for Startups

    可以看看别人都是如何思考的!原文地址:http://www.wired.com/magazine/2011/05/ff_ycombinator/all/1 Y Combinator Is Boot C ...

  5. Y combinator初创加速器2020冬季团队大赏——最好与最坏的时代

    Photo from TechCrunch Y Combinator是一家投资种子阶段初创公司的创投公司,一年举办两场集合优质初创公司的demo day,只对特定的投资人和媒体开放,Airbnb和Tw ...

  6. YC指的是Y Combinator和陆奇

    YC指的是Y Combinator(简称YC),是业界最著名.最有影响力的孵化器之一.YC的成功经验成为了众多创业公司和投资人追捧的典范,也成为了创业者们了解初创公司融资.交流经验的重要平台. YC的 ...

  7. 启动加速器比较:Y Combinator VS Techstars

    by Weiting Liu 刘伟廷 启动加速器比较:Y Combinator VS Techstars (Startup Accelerator Comparison: Y Combinator V ...

  8. 【逻辑与计算理论】组合子逻辑与 Y 组合子

    为什么是Y? 在前面的几个帖子里,我已经建立了如何把lambda演算变成一个有用的系统的点点滴滴. 我们已经有了数字,布尔值和选择运算符.我们唯一欠缺的是重复. 这个有点棘手.lambda演算使用递归 ...

  9. 【逻辑与计算理论】Lambda 演算——开篇

    原文来自Good Math/Bad Math的系列连载,全文分7章,本篇是第1章.中文博客负暄琐话对这个系列的前6章做过翻译,强迫症表示忍受不了「下面没有了」,于是自己动手做了全套.这里只对原文做了翻 ...

最新文章

  1. Linux重定向和管道符使用避坑指南
  2. 【内网穿透】生壳SSH映射 for Linux 使用教程
  3. WEB开发三层架构概述
  4. 【百战GAN】如何使用GAN拯救你的低分辨率老照片
  5. flask + react_再写一本 Flask 书
  6. golang 线程 Java线程_Golang 学习笔记(06)—— 多线程
  7. python六角形的绘制 编程_利用Python的turtle重复画六边形
  8. 内存经销商穷困潦倒 七元午饭都赊账
  9. [转] 关于SQLSERVER2000卸载与出现挂起问题的解决
  10. [Diary]6.12
  11. 摘抄:不注明来源,就是违反契约
  12. ROSCon 2019 机器人操作系统国际盛会
  13. 什么是Apple Pay?
  14. 杨海朝 mysql_老男孩Mysql高级DBA 实战新浪首席DBA 老男孩教育杨海朝老师全程主讲 老男孩Mysql视频...
  15. 现代诗一首 怀念。。。
  16. PHP 简易聊天室 利用redis的订阅发布功能
  17. Windows 7x64 Ultimate Modified by Michael
  18. 【深度学习】图像去雾,去噪里常用的相似评价指标:PSNR(峰值信噪比) SSIM(结构相似度)MSE(均方误差)
  19. 视频监控存储特点分析
  20. java 中常见日期格式的设置

热门文章

  1. 秒杀系统设计4要素:硬抗高并发,拒绝超卖,避免少卖,打击黄牛
  2. * 从控制台输入身份证号码,显示格式为: * ”xxx身份证的所有者是一位小哥哥/姐姐,xxxx年xx月xx日出生,今年xx岁!“
  3. 推荐一款 macOS 终端下自动配置系统代理的神器 ZSH-OSX-AutoProxy
  4. 吉洪诺夫 matlab,使用三种方法求解吉洪诺夫正则化参数,为什么结果相同
  5. Nginx 正向代理和反向代理
  6. imgaug数据增强实例
  7. win7 64位旗舰版系统
  8. java 数组最后一个_面试官: 100万个成员的数组取第一个和最后一个有性能差距吗?...
  9. 学会这些方法,win10效率提升9999%
  10. js前端动态生成变量及python后端动态生成变量接收