Comments (1)
深入lambda演算
id函数
实际上,前文我们讨论的id
函数,表明了一种态度。任意的数据都是函数
// λx.x
const id = x => x;
也就是说这里的x
也是一个函数,我们将使用函数的方式,推导我们所有的程序(lambda演算
和图灵状态机是等价的,一个用状态转移演算「计算」,一个用函数推演、归约来演算「计算」)
逻辑运算
最基本的演算使逻辑演算,它需要定义两个基元。
- True
- False
然后我们可以用逻辑基本量来表示一些运算
- 与 a && b
- 或 a || b
- 非 ~a
基元
现在,我们尝试用函数(演算式)表示逻辑基本量,并通过归约得到更多的操作符。
// λx.λy.x
const True = x => y => x;
// λx.λy.y
const False = x => y => y;
我们用函数表示了True
和False
的概念。True
得到两个参数,但永远只取第一个,False
得到两个参数,但永远只取第二个。注意:这里的x
和y
可以是任意数据,就像我们在前文说的,在lambda演算
中我们不关心数据本身,只关心这种「抽象形式」。虽然大多数情况下我们的数据都是「函数」。
逻辑与
再次声明,我们只关注这种「抽象形式」。逻辑与是这样的
- True True -> True
- True False -> False
- False True -> False
- False False -> False
在这个逻辑世界里,我们只能使用基元:True
和False
。
// λb1.λb2.b1 b2 b1
const And = b1 => b2 => b1(b2)(b1);
console.log(And(True)(False)); // False
console.log(And(True)(True)); // True
console.log(And(False)(True)); // False
console.log(And(False)(False)); // False
逻辑与And
操作,得到两个参数,他们都是基元类型(布尔值)。这里的运算很巧妙,我们调用第一个基元,给他传入两个操作,当他本身为True
时,返回第二个参数(True
的性质),当他本身为False
时,返回他自己(False
)。
如果看不明白,建议再多看几次,或者在浏览器里面跑一下上面的代码。
这样我们就得到了一个逻辑与
操作。
逻辑非
逻辑或和逻辑与类似,我们需要表示这种运算规则
- True False -> True
- True True -> True
- False True -> True
- False False -> False
参照逻辑与的代码,可以得到
// λb1.λb2.b1 b1 b2
const Or = b1 => b2 => b1(b1)(b2);
console.log(Or(True)(False)); // True
console.log(Or(True)(True)); // True
console.log(Or(False)(True)); // True
console.log(Or(False)(False)); // False
如果不明白,可以跑一下这段代码。
逻辑非
逻辑非是一个一元运算。一元运算指的是运算符只操作一个数据,而上面的逻辑与和逻辑或都需要两个数据参与,是二元运算。
既然是一元运算,就只需要用到基元就行了。
// λb.b False True
const Not = b => b(False)(True);
console.log(Not(True)); // False
console.log(Not(False)); // True
直接调用参数(是的,你可以理解为我们在进行归约了。),给两个参数值设置相反数据。非常棒!
条件运算
你还在惊讶函数能表示逻辑运算吗?函数不仅能做这件事,它还能表示条件运算。
在JavaScript
中,我们这么做。
function Condition(bool, left, right) {
return bool ? right : left;
}
还记得monad
的时候我们讲Either
吗?现在我们推演一下Either
。
// λb.λleft.λright.b left right
const Either = b => left => right => b(right)(left);
const Left = x => console.log('error:', x);
const Right = x => console.log('success:', x);
console.log(Either(True)(Left)(Right)); // Left
console.log(Either(False)(Left)(Right)); // Right
非常棒!这样的流程,就是在做lambda演算
了。
但你还需要注意,我们现在所有的演算都是「抽象形式」,是在一个抽象的概念内运算的,我们不关心x
、y
、left
、right
等演算参数究竟是什么,但我们的归约
行为,可以一直进行下去。
程序既然可以用状态机来表示,那么,我们现在也能用λ
表示了!
计算
终于涉及到「计算」了。小孩子学习自然数都是从1
开始,然后一个数字一个数字地数上去,稍微大一点后,才会在自然数的基础上去学习运算。
注意我刚才说的话
- 数
- 运算
实际上,我们的一个系统,都是由这样的两个概念构成的。
- 集合 = 基本集合定义 + 集合运算
- 自然数 = 基本数字 + 数字运算
- 社会 = 人 + 人与人之间的相互作用
- ...
如何用lambda演算
去抽象这种概念?
基元 + 操作!
// λf.λx.x
const Zero = f => x => x;
// λf.λx. f x
const One = f => x => f(x);
// ....
// λf.λx. f...f x
// const N = f => x => f...f(x)
定义一个基本元素x => x
,这就是我们的id
函数(identity
)。定义个操作f
不论f
表示什么,在自然数里面,它表示+1
,在负数里面它表示-1
,在阶乘里面,它表示!(n-1)
......总之,一个基元,对它重复执行操作,就得到了无数的数据。
这里的抽象仍然有效!我们不断地提取抽象的形式,这种思维方式,让我们不限于去做数字的加减乘除,有这个框架,可以表达一个域的概念!
是的,这会不会让你想起:monad
,Just
和map
就代表了数据和行为,这两个特性。有这两个特性,就可以表示一个范畴
(又回到了范畴论)
总结
学函数式编程,有兴趣的,一定要学一下haskell
,去体会美!
from basic-programming-knowledge.
Related Issues (20)
- 【VIM】编辑器相关整理
- 【Rust】资源汇总
- 【React】资源汇总
- 【tools】最有用的那些软件、站点-工具链
- 【英语】学习资源
- 【vim】文艺复兴·VIM使用指南·Day 1
- 【vim】文艺复兴·VIM使用指南·Day 2
- 【vim】文艺复兴·VIM使用指南·Day 3
- 【翻译】monio关于monad的解释
- 【函数式编程】函子 HOT 1
- 【异步】async/await比Promise好吗?
- 【杂文】述职报告的思考
- 【函数式编程】haskell语言-haskell趣学指南 HOT 5
- 【工程化】如何创建一个现代化的前端基础库
- wsl2开发环境设置排坑
- 前端库
- 【产品】构建一个产品需要哪些优秀的工具?
- 【docker】mac配置docker开发环境/用vscode远程编码/逐行解说
- 【nas】家用nas配置
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from basic-programming-knowledge.