Monads作为附属物
我一直在读类别理论中的单子。 monads的一个定义使用一对伴随函子。 monad是使用这些仿函数的往返定义的。显然,在类别理论中,附加是非常重要的,但我没有看到任何关于伴随函子的Haskell monad的解释。有没有人给它一个想法?
没有找到相关结果
已邀请:
5 个回复
碉罕城爸
,但在其他方面是独立的。 f(D - > C)和g(C - > D)之间的附加,写成f - | g,可以以多种方式表征。我们将使用counit / unit(epsilon / eta)描述,它给出了两个自然变换(仿函数之间的态射)。
请注意,coun中的“a”实际上是C中的身份函子,而单元中的“a”实际上是D中的身份函子。 我们还可以从counit / unit定义中恢复hom-set adjunction定义。
在任何情况下,我们现在可以从我们的单位/国家协议中定义一个Monad,如下所示:
现在我们可以实现(a,)和(a - >)之间的经典附加:
现在是一个类型的同义词
如果我们在ghci中加载它,我们可以确认State正是我们的经典状态monad。请注意,我们可以使用相反的组合并获取Costate Comonad(也就是商店comonad)。 我们可以用这种方式制作一些其他的附加功能(例如(Bool,)),但它们有点奇怪的单子。不幸的是,我们不能以令人愉快的方式直接在Haskell中执行引导Reader和Writer的附加功能。我们可以做Cont,但正如copumpkin所描述的那样,它需要来自相反类别的附加,所以它实际上使用了“伴随”类型类的不同“形式”来反转某些箭头。该形式也在附属包中的不同模块中实现。 Derek Elkins在Monad Reader 13中的文章以不同的方式介绍了这一材料 - 用类别理论计算单子:http://www.haskell.org/wikiupload/8/85/TMR-Issue13.pdf 此外,Hinze最近的Kan扩展程序优化论文还介绍了从
和
之间的附件中构建monad列表:http://www.cs.ox.ac.uk/ralf.hinze/Kan.pdf 老答案: 两个参考。 1)类别附加物一如既往地传递附加物的表示以及它们如何产生单子。像往常一样,很好地思考,但很好的文档:http://hackage.haskell.org/packages/archive/category-extras/0.53.5/doc/html/Control-Functor-Adjunction.html 2)-Cafe还提供了关于附加作用的有希望但简短的讨论。其中一些可能有助于解释类别附加:http://www.haskell.org/pipermail/haskell-cafe/2007-December/036328.html
寿柬窟年
逆变函子与其自身组合而产生的,因为它恰好是自我伴随的。这就是你如何得到它的
。然而,它的反对导致双重否定消除,这不能用Haskell写出来。 对于一些说明并证明这一点的Agda代码,请参阅http://hpaste.org/68257。
嘘崇蔡对
为monad
(
和
) 并考虑T代数
。 (注意
是一个自由的幺ѭѭѭ,即身份
和乘法
。) 根据定义,
必须满足
和
。 现在,一些简单的图表追逐证明
实际上诱导了一个幺半群结构(由
定义), 并且
成为这种结构的幺半群同态。 相反,Haskell中定义的任何幺半群结构
自然地定义为T-代数。 通过这种方式(
,'用'28'替换'
,并将
映射到
,该身份的功能)。 因此,在这种情况下,T-代数的类别只是在Haskell,HaskMon中可定义的幺半群结构的类别。 (请检查T-algebras中的态射实际上是单态同态。) 它还将列表描述为HaskMon中的通用对象,就像Grp中的免费产品,CRng中的多项式环等。 对应于上述结构的调整是
哪里
,它取一个类型为'由'33'生成的'自由幺半群',即
,
,健忘的算子(忘记乘法),
,由
定义的自然变换,
,由上述折叠函数定义的自然变换 (从一个自由的幺半群到它的商幺'的'规范投射') 接下来,还有另一个'Kleisli类别'和相应的附加功能。 你可以检查它只是具有态射H39ѭ的Haskell类型, 它的成分由所谓的“Kleisli成分”
给出。 典型的Haskell程序员会发现这个类别更为熟悉。 最后,如CWM中所示,T-代数的类别 (相应的Kleisli类别)成为类别中的终端(resp.initial)对象 在合适的意义上定义列表单子T的辅助剂。 我建议对二叉树仿函数
进行类似的计算以检查你的理解。
钨蜡唤喉晤
)和函数映射(例如,映射到列表的标准应用)组成。代数添加从列表到元素的映射。一个例子是添加(或乘以)整数列表的所有元素。仿函数
采用任何类型,例如Int,并将其映射到Int列表中定义的代数,其中产品由monadic join定义(反之亦然,join定义为产品)。健忘的算子
取代数并忘记了产品。然后使用伴随仿函数对
,
以通常的方式构造monad。 我必须说我不是更聪明的人。
仇聘发栖
,存在对Kle10ѭ的Kleisli类别的唯一附加。 在Haskell中,monad的使用主要局限于此类别的操作 (基本上是一类免费代数,没有商)。 事实上,所有人都可以用Haskell Monad来组成一些Kleisli态射 键入
通过使用do表达式,
等来创建新的 射。在这种情况下,monad的作用仅限于经济 表示法。一个利用态射的相关性能够写(比如说)
而不是
,也就是说,你可以把序列写成序列, 不是一棵树。 即使使用IO monads也不是必需的,因为当前的Haskell类型系统功能强大 足以实现数据封装(存在类型)。 这是我对原始问题的回答, 但我很好奇Haskell专家对此有何看法。 另一方面,正如我们已经注意到的那样,monad和。之间也存在1-1的对应关系 (T-)代数的附加。按照麦克莱恩的说法,选择是一种方式 表达类别的等价性。 在adj53ѭ的典型设置中,
是某种类型 '自由代数发生器'和G''健忘的仿函数',相应的monad 将(通过使用T-代数)描述
的代数结构是如何(和何时)构造在
的对象上的。 在Hask和列表monad T的情况下,
引入的结构是 of monoid,这可以帮助我们通过代数建立代码的属性(包括正确性) 幺半群理论提供的方法。例如,函数
可以 只要
是一个幺半群,很容易被视为联想操作, 可以由编译器利用的事实来优化计算(例如,通过并行)。 另一个应用是使用分类来识别和分类函数式编程中的“递归模式” 希望(部分)处理'函数式编程的转向',Y(任意递归组合器)的方法。 显然,这种应用程序是类别理论创建者(MacLane,Eilenberg等)的主要动机之一, 即,建立类别的自然等价,并将一种众所周知的方法转移到一个类别中 到另一个(例如拓扑空间的同源方法,编程的代数方法等)。 在这里,adjoints和monad是利用这种类别连接不可或缺的工具。 (顺便提一下,monad(及其双重,comonads)的概念是如此普遍,以至于人们甚至可以定义'cohomologies' Haskell类型。但我还没有想过。) 至于你提到的非决定性功能,我更不用说了...... 但请注意;如果某个类别
的附加
定义了monad
列表, 必须有一个独特的“比较函子”
(Haskell中可定义的幺半群类别),见CWM。 实际上,这意味着您的兴趣类别必须是某种限制形式的幺半群类别(例如,它可能缺少一些商而不是免费代数)以便定义列表monad。 最后,一些评论: 我在上一篇文章中提到的二叉树仿函数很容易推广到任意数据类型
。 也就是说,Haskell中的任何数据类型都自然地定义了monad(连同相应的代数类别和Kleisli类别), 这只是Haskell中任何数据构造函数的结果。 这是我认为Haskell的Monad类不仅仅是语法糖的另一个原因 (当然,这在实践中非常重要)。