范畴论玩具:什么是单子 (monad)?
对于上了计概课的同学们, 相信大家都有很多问号, 什么是 monad 捏?
monad 就是自函子范畴上的一个"幺半群" (?)
我们来尝试理解一下这句话在说什么, 首先这里的"幺半群"是在通常意义上的幺半群的一个推广, 也就是说知道什么是幺半群的同学可以先忘掉原有概念
一个范畴 category 是指下述资料:
- 一些对象, 构成集合 ;
- 一些态射, 构成集合 , 以及映射 给出态射的来源和目标, 从而对于 , 表示 到 的态射构成的集合, 称为 -集;
- 对于 都有恒等态射 ;
- 对于 都有运算 , 其将 映至 , 满足下述性质:
- 对于 , 若 和 都有定义, 则 .
- 对于 , 都有 .
对象很好理解, 就是一些元素...吗? 大多数时候, 我们应该把对象看作具有某种代数结构的集合, 而态射就是保持这些代数结构的映射.
我们有成堆的数学上的例子, 当然这都不重要, 就看看下面两个:
- 全体集合作为对象构成范畴 , 态射及其合成是自明的;
- 对于偏序集 , 我们构造范畴 如下: 其对象即为 , 而对 若 则存在唯一态射 , 否则不存在态射. 特别地, 对于 , 将 看作序数等同于全序集 , 这样构作的范畴记为 .
虽然但是, 我们好像是学 Haskell 的, 那就来看看这是怎么扯上关系的.
定义范畴 的对象是 Haskell 语言的所有类型 a
, 态射是所有函数 f :: a -> b
, 态射的合成是运算符 (.) :: (b -> c) -> (a -> b) -> a -> c
.
接下来就引出描述范畴之间态射的概念, 称为函子 functor, 它们要保持一个范畴所具有的"代数结构", 即对象之间的态射及其合成.
对于范畴 , 一个函子 是指下述资料:
- 对象间的映射 ;
- 对于 有态射间的映射 使得 , .
对应到 Haskell 语言中, 因为我们现在还只有 这个范畴, 所以只能考虑 到 的函子, 这样的函子称为自函子 endofunctor, 写成代码就是大家熟悉的这个样子:
这样的 f
称为类型构造器 type constructor, 其将一个类型"包装"为另一个类型, 注意不要与类型 type 搞混了.
有了 Functor
类之后, 在实践过程中我们会遇到 Maybe (Maybe a)
这样的东西, 这启发我们考虑函子的"合成运算", 甚至还有函子之间的态射, 而无聊的 Haskell 设计者们怎么会放过又一次提升抽象层次的机会呢 (?), 即所有自函子构成一个范畴, 称为自函子范畴 endofunctor category, 记作 , 为此我们需要一些准备工作.
对于函子 , 定义自然变换 natural transformation 是指一族态射 使得下图对 中的态射 交换:
图表交换是指对于起点和终点相同的路径, 其上态射的合成相同, 例如上面的图表就是 .
"自然"在数学上指的是能画出来的图表可交换, 翻译到 Haskell 语言, 实际上是说对于相同的对象构造的函数, 在类型确定的情况下是唯一的, Transformation
类的定义如下:
至于函子间合成怎么办捏? 我们要在范畴上定义二元运算, 这引出幺半范畴 monoidal category 的概念. 为了简化理论我们只讨论严格幺半范畴 strict monoidal category, 这是说在范畴 上有二元函子 和幺元 使得 且 . 容易验证自函子 构成严格幺半范畴.
严格幺半范畴上的幺半对象 monoid object, 简称 monoid 错误地直译为幺半群是指对象 附带乘法 和幺元 满足结合律和幺元性质, 即如下的交换图表:
自函子范畴上的幺半对象即为单子 monad. 完成目标, 完结撒花 (?)
先看看远处的错误翻译"幺半群", 实际上不无道理! (哈?)
作为幺半范畴, 其上的幺半对象确实是通常意义上的幺半群, 因而是一个推广定义!
再重复一遍: 具体到实际意义上时 是函子 (类型构造器) 而 和 都是自然变换, 而自然变换在定义上是对全体类型 a
的一族态射 (函数).
还是以无聊的 Maybe
举例子, 称为 join
函数, 将 Maybe (Maybe a)
映至 Maybe a
, 称为 unit
函数, 也记作 pure
, return
, 将 a
映至 Maybe a
, 写成代码就是大家熟悉的这个样子:
这里的 (>>=)
是个啥捏? 这就涉及到 monad 在 Haskell 中的具体应用, 例如实现管道操作和 do
语法糖, 与本文讲述理论的主题没啥关系, 而且大家在计概课也有学(
实际上, join
与 (>>=)
可以按照下述方式互相定义:
相信大家确实理解 monad 是什么了, 于是就真的完结撒花了)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
2019-10-12 ZROI Day6比赛总结