Tambara装备
摘要
本文解释了范畴论中的Tambara模块,它们与幺半群函子和profunctor光学的关系,并使用Haskell代码说明这些概念,内容基于Mateusz Stroiński近期的一篇论文。
暂无内容
查看缓存全文
缓存时间: 2026/07/15 22:46
# Tambara 装备
来源:https://bartoszmilewski.com/2026/07/11/tambara-equipment/
我最初被范畴论吸引,是因为想理解 Haskell 的光学(optics)。van Laarhoven 的函子表示和 Kmett 对 Tambara 模的使用让我感到困惑。通过用 Yoneda 引理玩俄罗斯方块,我取得了一些进展,攻破了越来越深奥的主题。在牛津应用范畴论 Adjoint School(https://www.appliedcategorytheory.org/adjoint-school-act-2019/)的一群研究人员和学生的合作下,我们解决了遍历光学(traversal optics)的问题,并发表了一篇论文(https://compositionality.episciences.org/13530/pdf),总结了余函子光学(profunctor optics)的进展。
光学位于幺半群作用(monoidal actions)和 Tambara 模的交汇处。光学与 Tambara 表示之间存在对偶性。这与数学家所说的 Tannakian 重建有关,即从一个代数对象的所有表示中恢复出该对象本身。
难怪最近 Mateusz Stroiński 的文章《模范畴、内部双模与 Tambara 模》(https://arxiv.org/abs/2210.13443v1)引起了我的兴趣。原来 Tambara 模可以被视为双范畴中的水平箭头,而双范畴也是一种 Proarrow 装备。我将尝试勾勒这篇论文的内容,并用 Haskell 代码加以说明。
口号是:Tambara 模之于幺半群函子,正如余函子之于函子。
双范畴设定下的 Tambara 模的主要优势在于,它可以直接用于丰富范畴(enriched categories)。
## 幺半群函子重述
为简单起见,我将使用一个简化版的严格幺半群函子(https://bartoszmilewski.com/2026/06/30/actegories/),它从幺半群范畴的定义中省略了对象约束:
这里,`alpha'` 是 `alpha` 的逆。
幺半群函子可以复合:
复合结果仍然是幺半群函子:
注意使用类型应用来帮助 Haskell 类型检查器。
## Tambara 模
Tambara 模是一种与幺半群范畴的作用相容的余函子。如果将余函子解释为一种证明相关的二元关系,那么 Tambara 模具有这样的性质:当两个对象相关时,用同一个对象 `m` 对它们进行“乘法”后,它们仍然相关。这里的乘法指的是幺半群范畴 \mathbf M 的作用。换句话说,Tambara 模是一个配备了变换的余函子 J \colon A^{op} \times B \to \mathbf{Set}:
\lambda_{m a b} \colon J a b \to J (m \triangleright_1 a) (m \triangleright_2 b)
该变换在 a 和 b 上是自然的,在 m 上是 dinatural 的。该作用与幺半群结构良好地交互:
\lambda_{(m \otimes n) a b} = \lambda_{m (n \triangleright a) (n \triangleright b)} \circ \lambda_{n a b}
\lambda_{1 a b} = id
(需要一些结合子和单位子修正)。
我们可以在 Haskell 中将其表示为类型类:
我选择专注于作用范畴的*左作用*,但也可以轻松定义右作用或两者兼有。为简单起见,我对两个参数使用了相同的作用。在一般情况下,我们会有两个独立的作用范畴。
Tambara 模最简单的例子是 hom-余函子:
这里我使用了作用的双函子性质。
Tambara 模构成一个范畴,其中保持作用的自然变换作为态射。
使用余端(coend)的常见余函子复合也适用于 Tambara 模。
复合结果仍然是 Tambara 模:
综上所述,我们有一个双范畴 \mathbf{Tam},其中作用范畴是 0-胞腔,带余端复合的 Tambara 模是 1-胞腔,它们之间的自然变换是 2-胞腔。
此外,内 Tambara 模(即在单一范畴内作用的 Tambara 模)构成一个*幺半群*双范畴,其中余函子复合充当张量积,hom-余函子充当单位元。
## Tambara 装备
我们之前研究过一个双范畴 \mathbb{P}rof,其中范畴是 0-胞腔,余函子是水平箭头,函子是垂直箭头,自然变换是 2-胞腔。这个双范畴恰好是一种 Proarrow 装备(https://bartoszmilewski.com/2026/04/24/profunctor-equipment/),它以特定方式将函子与可表示的余函子联系起来。
事实证明,存在一种类似的构造,其中作用范畴是 0-胞腔,Tambara 模是水平 1-胞腔,幺半群函子是垂直 1-胞腔。为了形成 2-胞腔,我们首先需要能够沿着一对幺半群函子提升(或*限制*)一个 Tambara 模。我们将 J 的提升定义为余函子:
\langle a, c \rangle \mapsto J(f a)(g c)
或者使用占位符,J(f -) (g =) 在 Haskell 中表示如下:
Tambara 模的提升仍然是 Tambara 模,其结构映射定义为复合:
J (f a) (g c) \xrightarrow{\lambda_{m (f a) (g c)}} J (m \triangleright_2 f a) (m \triangleright_2 g c) \xrightarrow {J \alpha^{-1} \alpha} J (f (m \triangleright_1 a)) (g (m \triangleright_1 c))
第二个箭头将(可逆的)幺半群函子结构映射提升到 J:
\alpha \colon m \triangleright_2 g c \to g (m \triangleright_1 c)
以下是 Haskell 中的相同实现:
我使用类型应用来选择对应于 `act2` 的正确左作用。
2-胞腔则是从 H 到 J 的提升的自然变换。
[](https://i0.wp.com/bartoszmilewski.com/wp-content/uploads/2026/04/Screenshot-2026-04-18-at-16.48.46.png?ssl=1)
或者,在 Haskell 中:
同伴(companion)和共轭(conjoint)是可表示的余函子,只要 `f` 是幺半群函子(`Identity` 函子平凡地是幺半群的),它们自动是 Tambara 模:
同伴和共轭的单位元和余单位元胞腔相对容易定义(参见链接的代码)。
## 自由 Tambara 与光学
存在一个明显的遗忘函子从 \mathbf{Tamb} 到 \mathbf{Prof}(它忘记作用)。这个函子有一个左伴随。对于任何余函子 J,它生成一个自由 Tambara 模,由以下余端给出:
(\Phi J) \, s t = \int^m \int^{x y} C(s, m \triangleright x) \times J x y \times C(m \triangleright y, t)
在 Haskell 中,我们将其建模为存在数据类型:
结果确实是 Tambara 模:
巧合的是,光学可以被定义为作用在可表示余函子 \Theta_{a b} x y = C(x, a) \times C(b, y) 上的自由 Tambara 模。实际上,应用 Yoneda 归约,我们得到:
O\, s t a b = \int^{m} C(s, m \triangleright a) \times C(m \triangleright b, t)
在 Haskell 中:
给出:
经过 Yoneda 归约,它同构于:
## 内化幺半群作用
幺半群作用,作为函子 ![\mathbf M \to [C, C]](https://s0.wp.com/latex.php?latex=%5Cmathbf+M+%5Cto+%5BC%2C+C%5D&bg=ffffff&fg=29303b&s=0&c=20201002),如果它有右伴随,则可以在 M 中内化:
C(m \triangleright a, t) \cong \mathbf M (m, \{a, t \} )
如果你把作用看作“乘法”,那么这个伴随关系类似于柯里化,而右伴随则扮演了“内部 hom”的角色。
在 Haskell 中,我们定义一个类型类:
我们可以利用这个伴随关系来简化乘法光学:
\int^{m} C(s, m \triangleright a) \times C(m \triangleright b, t) \cong \int^{m} C(s, m \triangleright a) \times \mathbf M (m, \{b, t \})
使用 Yoneda 归约(即对 m 进行“积分”),这等价于:
O \, s t a b \cong C(s, \{b, t \} \triangleright a )
对于加法光学,我们使用余积的右伴随,在乘积范畴中产生 hom 集。
这两种技巧都用于简化遍历(traversals),它们是由多项式函子生成的光学:
![\int^{c \colon [\mathbb N , Set]}} C(s, \sum_n c_n \times a^n) \times C (\sum_m c_m \times b^m, t)](https://s0.wp.com/latex.php?latex=%5Cint%5E%7Bc+%5Ccolon+%5B%5Cmathbb+N+%2C+Set%5D%7D+C%28s%2C+%5Csum_n+c_n+%5Ctimes+a%5En%29+%5Ctimes+C+%28%5Csum_m+c_m+%5Ctimes+b%5Em%2C+t%29&bg=ffffff&fg=29303b&s=0&c=20201002)
这里,c 是一个自然数索引的对象族,具有由卷积给出的幺半群结构;a^n 和 b^n 是幂。
我们首先使用余积伴随:
C (\sum_m c_m \times b^m, t) \cong \prod_m C(c_m \times b^m, t)
然后跟随柯里化伴随。我们得到遍历的公式:
T \, s t a b \cong Set(s, \sum_n Set(b^n, t) \times a^n)
结果可以在 Haskell 中通过将幂替换为列表来说明:
## 内部幺半群
内 hom\{a, a\} 自动是 \mathbf M 中的幺半群。实际上,我们可以定义幺半群乘法为:
\mathbf M(\{a, a\} \otimes \{a, a\}, \{a, a\}) \cong C\big((\{a, a\} \otimes \{a, a\}) \triangleright a, a\big)
右侧可以通过双重应用伴随的余单位元来实现:
\epsilon_{a a} = \{a, a\} \triangleright a \to a
在 Haskell 中,我们首先在幺半群范畴内部定义一个幺半群:
然后证明 `hom a a` 是它的一个实例:
其中伴随的余单位元是 `eval` 函数:
本文的 Haskell 代码可在此处(https://v15.next.forgejo.org/BartoszMilewski/Categories/src/branch/main/src/Tambara.hs)获取。
相似文章
Haskell中的Profunctor装备
这篇博客文章提供了一个用Haskell实现的Profunctor装备的玩具实现,包括自然变换和组合,旨在让范畴论概念对程序员来说更易于理解。
Actegories
一篇解释范畴论中Actegories概念及其在编程光学(如lenses和prisms)中作用的文章,并包含Haskell实现。
@fedebruzzone7: 从范畴论的角度:CuTe 布局的范畴基础 https://arxiv.org/abs/2601.05972
本文引入了一个范畴框架来形式化 NVIDIA 的 CUTLASS 库中的布局代数,定义了范畴和态射以表征张量布局,并提供了一个 Python 实现以及兼容性证明。
Data types à la carte (2008)
本文提出了一种从独立组件组合数据类型和函数的技术,并将该方法扩展到结合自由单子,从而实现了对Haskell的IO单子的模块化结构。
余代数和自动机
一份介绍性的 literate Haskell 文档,探讨余代数和自动机之间的关系,展示如何利用范畴论中的 fold 和 unfold 操作来建模状态机。