Y-Combinator不同语言实现方案

简介:

递归和定点

纯λ演算的一大特色是可以通过使用一种自应用技巧来书写递归函数。

f(n) = if n = 0 then 1 else n*f(n-1) 
f = λn.if n = 0 then 1 else n*f(n-1)

把f移到等式的后面,得到函数G

G = λf.λn.if n = 0 then 1 else n*f(n-1)

很显然有:

f = G(f)

这表明递归声明涉及找出定点。 函数G的定点是指满足f=G(f)的f的值。在λ演算中,定点由定点操作符Y来定义。 具体的推导过程可以参考我的上一篇文章Y-Combinator的推导

Y = λf.(λx.f(x x))(λx.f(x x))

Ruby 版本

def y(&gen)
    lambda {|g| g[g] }.call(lambda{|f| lambda {|*args| gen[f[f]][*args] }})
end

factorial = y do |recurse|
    lambda do |x|
        x.zero? ? 1 : x * recurse[x-1]
    end
end
puts factorial.call(10)

Python 版本

def y_combinator(gen):    
    return (lambda g: g(g))(lambda f: (lambda *args: (gen(f(f)))(*args)))

ret = y_combinator(lambda fab: lambda n: 1 if n < 2 else n * fab(n - 1))(10)
print(ret)

JavaScript 版本

function y(gen) {
    return (function(g) {
        return g(g);
    })(function(f) {
        return function(args){
            return gen(f(f))(args);
        };
    });
}

var fact = y(function (fac) {
    return function (n) {
        return n <= 2 ? n : n * fac(n - 1);
    };
});
console.log(fac(5));

Clojure 版本

(defn Y [gen]
  ((fn [g] (g g))
    (fn [f]
      (fn [n] ((gen (f f)) n)))))

(defn fac-gen [f] (fn [n] (if (<= n 0) 1 (* n (f (dec n))))))
(assert (= ((Y fac-gen) 5) 120))

参考

  1. Lambda演算之自然数
  2. Y-Combinator的推导(Clojure描述)
  3. Y-Combinator的推导(JavaScript描述)
目录
相关文章
|
8月前
|
Linux 测试技术 C++
【代码实践】编码精粹:打造高效与可维护的代码艺术
【代码实践】编码精粹:打造高效与可维护的代码艺术
162 0
|
2月前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
130 4
|
2月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
119 1
|
3月前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
45 1
|
4月前
|
IDE C# 开发工具
C# 语言的主要优势是什么?
C# 语言的主要优势是什么?
167 2
|
5月前
|
Rust 安全 程序员
Rust 语言的防错机制太惊人了!安全编码从此不再是难题,快来一探究竟!
【8月更文挑战第31天】《安全编码原则:Rust 语言中的防错机制》探讨了代码安全的重要性,并详细介绍了Rust语言如何通过内存安全模型、所有权与借用规则等特性,在编译阶段检测并阻止潜在错误,如缓冲区溢出和悬空指针。文章还讨论了类型安全、边界检查等其他安全特性,并提出了遵循不可变引用、避免裸指针及充分测试等实用编码原则,以进一步提升代码质量和安全性。随着Rust在软件开发中的应用日益广泛,掌握其安全编码原则变得尤为重要。
79 0
|
6月前
|
存储 缓存 编译器
编程语言性能优化:黑盒法和数字处理的支持
【7月更文挑战第7天】该文主要讨论了编程中的性能优化技术,特别是针对哈希表查找中模运算的优化。性能优化在不同场合方式不一样,文章强调了分析器在定位性能问题中的重要性,并指出优化应基于对底层架构的理解。
79 3
编程语言性能优化:黑盒法和数字处理的支持
|
6月前
|
缓存 编译器 Shell
回顾go语言基础中一些特别的概念
【7月更文挑战第6天】本文介绍Go语言基础涵盖包声明、导入、函数、变量、语句和表达式以及注释。零值可用类型如切片、互斥锁和缓冲,支持预分配容量以优化性能。
64 2
回顾go语言基础中一些特别的概念
|
8月前
|
存储 算法 安全
C++语言深度探索:从基础到实践
C++语言深度探索:从基础到实践
46 2
|
8月前
|
Rust 安全 前端开发
Rust还是其他语言:考量因素与案例分析
【2月更文挑战第1天】本文将探讨在选择编程语言时,为什么Rust可能会成为理想的选择。我们将分析Rust的主要优势,如内存安全、性能、并发编程和所有权系统,并将其与其他流行的编程语言进行比较。此外,我们还将通过具体的案例分析,展示Rust在实际应用中的优势和应用场景。