标签:11 Box 函数 一个 编程 单子 类型 函子
![](/i/l/?n=23&i=blog/3076680/202301/3076680-20230119090349106-122939327.png)
1. 范畴论
1.1. 范畴论是数学的一个分支,研究的是由对象及这些对象之间的箭头组成的结构
1.2. 函子和单子的概念来自范畴论
1.3. Haskell是一种编程语言,从范畴论中汲取了许多灵感,所以它的语法和标准库很容易表达函子、单子和其他结构的概念。Haskell完全支持高阶类型
2. 函子(functor)
2.1. 函子是执行映射操作的函数的推广
2.2. 对于任何泛型类型,以Box‹T›为例,如果map()操作接受一个Box‹T›和一个从T到U的函数作为实参,并得到一个Box‹U›,那么该map()就是一个函子
2.3. 大部分主流语言都没有很好的方式来表达函子
2.4. 函子的常规定义依赖于高阶类型的概念
2.5. 函子能够在处理管道中传送最初的错误,但是如果管道中的每个步骤都可能失败,函子就无法工作
3. 高阶类型
3.1. 与高阶函数类似,代表具有另外一个类型参数的类型参数
3.2. T‹U›或Box‹T‹U››有一个类型参数T,后者又有一个类型参数U
3.3. 高阶类型是接受其他种类作为实参的种类(参数化的类型构造函数)
3.4. 理论上,我们可以深入任何级别,如T‹U‹V‹W›››
3.5. 在实际应用中,超过第一个T‹U›级别后,它就没那么有用了
3.6. TypeScript、C#或Java中没有一种好的方式来表达高阶类型,所以我们不能通过使用类型系统表达一个函子的方式来定义结构
3.7. Haskell和Idris等语言有更强大的类型系统,使得创建这种定义成为可能
4. 类型构造函数
4.1. 返回类型的一个函数
4.2. 每个类型都有一个构造函数
4.3. 类型number的构造函数看作不接受实参、返回number类型的一个函数,也就是() -› [number type]
5. bind()
5.1. 在Box‹T›上应用函数T =› Box‹U›,返回一个Box‹U›
6. map()
6.1. 在Box‹T›上应用函数T =› U,返回一个Box‹U›
7. 区别在于如何得到这个Box‹U›
8. 单子
8.1. 由bind()和return()或unit()的函数组成
8.2. return()或unit()
8.2.1. 接受一个类型T,并将其封装到泛型类型中,例如Box‹T›、T[]、Optional‹T›或Either‹Error, T›
8.3. 以泛型的方式编写程序,同时将程序逻辑所需的样板代码封装起来
8.3.1. 推广到各种列表:数组、链表和迭代器范围
8.3.2. 可以把一系列函数调用表达为一个管道,将数据管理、控制流或副作用抽象出去
8.3.3. 单子在错误传播、异步代码和序列处理的上下文中很有用
8.4. 如果一种编程语言不能表达高阶类型,就没有一种很好的方式来指定一个Monad接口
8.5. 大部分主流语言仍然把单子视为模式,而不是结构,但它们肯定是有用的结构,所以能够在不同的上下文中一再出现
8.6. 单子模式
8.6.1. 单子是一个泛型类型H‹T›。对于该类型,我们有一个函数(如unit())可接受类型T的一个值并返回类型H‹T›的一个值。还有一个函数(如bind())可接受类型H‹T›的一个值和一个从T到H‹U›的函数,并返回类型H‹U›的一个值
8.7. continuation单子
8.7.1. promise代表在将来某个时候发生的计算的结果
8.7.2. 链接promise是几乎所有主流编程语言都提供的一种API,它实际上就是单子性的
8.7.3. promise是封装了调度/异步执行的单子
8.8. 列表单子
8.8.1. 受一个T数组和从T到U数组的一个函数,并返回一个U数组
8.8.2. bind()接受一个T的序列和一个T =› U的序列的函数。其结果为一个压平的U列表
8.9. 状态单子
8.9.1. 封装一个状态,并把该状态与值一起传递
8.9.2. 在给定当前状态时,它将生成一个值和一个更新后的状态
8.10. IO单子
8.10.1. 封装了副作用
8.10.2. 允许我们实现能够读取用户输入或者写入文件或终端的纯粹函数,因为不纯粹的行为从函数中移除了出来,封装到了IO单子中
9. 函数式编程
9.1. 与面向对象编程区别很大的范式
9.1.1. 提供另外一种思考代码的视角
9.2. lambda和闭包、不可变的数据结构以及反应式编程都来自函数式编程语言
9.3. Haskell作为入门语言。它的语法相当简单,但类型系统十分强大,而且它有着牢固的理论基础
10. 泛型编程
10.1. 理论基础是抽象代码
11. 线性类型
11.1. 线性逻辑与处理资源的经典逻辑不同
11.2. 在经典逻辑中,如果一个演绎为true,就永远为true,但线性逻辑证明不符合这种演绎
11.3. 对于理解线性类型及其应用,Rust是一种很好的语言
12. 从属类型
12.1. 在泛型中,一个类型可以决定另外一个类型是什么(类型参数)
12.2. 从属类型则颠倒了这种情况:值决定了类型
12.3. 对于理解从属类型及其应用,Idris是一种很好的语言
标签:11,
Box,
函数,
一个,
编程,
单子,
类型,
函子
From: https://www.cnblogs.com/lying7/p/17061051.html