目录
此条目是关于单子如已知范畴代数但在应用于计算机科学。另请参阅单音(消歧).
目录
想法
在计算机科学,一个(钴-)单子(或(钴-)Kleisli三重,或(共同)扩展系统)是一种数据类型-描述“计算概念”的结构[莫吉(1989),莫吉(1991)]可能“具有外部影响或受到外部环境/原因的影响”,例如涉及随机存取存储器,输入/输出,异常处理,正在写入或从中读取全局变量等命令式编程但被转换为具有确定性和可证实的行为,风格为函数式编程.
简而言之,一个(“扩展系统-样式“[马内斯(1976),例3.12]或“Kleisli三重-样式“[Moggi(1991),定义1.2])单子在给定的程序设计语言包括作业(但请参见在下面):
-
到任何数据 类型 新数据类型的第页,共页“-具有的数据-效果”,
-
到任何一对属于-有效的功能表单的(程序)和有效复合函数的(他们的结合或克莱斯利成分),
-
到任何数据 类型 函数的分配“琐碎”-效果”,
这样,绑定相联的还有单作的关于返回操作,因此数据类型具有-它们之间的有效程序构成类别(该Kleisli类别给定效果/单子).
我们现在更详细地解释这意味着什么以及它有什么好处。
基本思想:单子效应
在编程通常情况下程序具有“标称”输出数据类型 事实上的输出某些修改类型的数据这说明了该计划造成的“外部影响”,其中
(1)
是发送一般操作吗数据类型 到新数据类型.
例如,如果在计算其标称输出数据的同时程序还写入日志消息 字符串,则其实际输出数据为一对 属于产品类型 .
或者,如果程序可能失败,而“抛出例外消息“ 字符串,则其实际输出数据为任何一个 或 ,因此属于副产品类型 .
给定这样一个-有效程序并给出了后续程序接受类型的标称输入数据而且它本身可能涉及到类型的进一步影响,然后是天真 作文这两个程序中没有任何意义(除非实际上是一种微不足道的效果),但它们很明显有意的显然,通过以下方法可以获得成分:
-
第一次调整通过给定的处方
(2)
这样的话:
-
不接受类型为的数据和
-
“充当虽然运送任何以前的-影响”(这种直觉在下面成为一个正式的事实(9));
-
然后形成天真作文
如下:
(注意,我们用““里面有什么程序设计语言喜欢哈斯克尔 表示为“(-)>>=编程
又称“鱼记法”,例如。Milewski 2019第321页一些作者用上标表示,”“,例如。莫吉(1991);乌斯塔鲁(2021),第1讲,第12页.)
根据这些程序的预期行为,仍需具体说明“携带-影响”,因此“绑定”操作是什么(2)具体来说。
例如,在上面的日志效果示例中,其中,显而易见的方法是使用串联 并设置:
在上面的另一个示例中,其效果是可能抛出例外信息,传递这种效果的明显方式是使用共对角线的 ,相当于继续转发已引发的异常(如果有):
无论选择什么样的设计来“传递效果”,都必须将该方法应用于三倍的属于-名义上可组合的有效程序,则其有效组合应明确定义为相联的,满足以下要求方程式–这里称为第一个“单子定律”:
(3)
最后,为了使这种有效程序的概念有效地连接到没有效果的“纯”程序,对于任何程序来说都应该是这样的碰巧没有-效果,我们有一个如何将其视为-以琐碎的方式执行有效的程序。为此,应定义一个操作
(4)
它只“返回”类型的数据,但被重新视为有效-琐碎的数据;这样我们就可以构建一个微不足道的有效程序.
例如,在上面的日志消息效果示例中,这将是操作分配空的 一串 .
在上面的另一个示例中异常处理,微不足道的影响只是不抛出异常,这只是(右边共投影进入副产物).
最后的一致性条件(即剩余的“单子定律”)是“携带琐碎效应确实是琐碎操作”,即
(5)
请注意结合性条件(3)和统一性条件(5)共同等同于说数据类型具有家庭成员属于-在上述意义上,它们之间的有效程序形成了一个类别.英寸范畴理论这被称为Kleisli类别 的单子 上类别 属于数据类型中间有程序:
(6)
传统上在范畴理论,的公理在单子以不同的方式呈现,调用monad“product”自然转化 而不是“绑定”操作。我们可以很容易地检查单体的这两个公理表示实际上是相等的-参见(7)下面–,但上面“Kleisli三重/扩展系统“-演示通常与函数式编程.
总之,可以选择作业(但请参见在下面)至数据类型 属于
-
,
即类型-名义类型的有效数据 (1);
-
,
即如何执行程序,同时执行任何先前的效果(2);
-
,
即如何看待平淡-数据的影响微不足道(4)
从属于:
-
这个结合性条件(3)
-
这个统一性条件(5)
称为计算机科学中的单子(同时:“Kleisli三重“在中函数式编程)并用于编码所有程序都可能受到外部效应某种程度上这是由上面选择的monad操作指定的。
这里,暂时(但请参阅在下面),我们写对于设置获取类型数据的程序/函数到的数据(该hom集合在平原上类别属于类型).
上面的第一个运行示例称为作家莫纳德,因为它对程序可能具有将消息字符串写入给定缓冲区的附加效果的情况进行编码。
上面的另一个运行示例自然称为异常单子.
与单体的其他常见公理的关系。上述Kleisli/扩展结构,使克莱斯利风格 计算机科学中的单子、可能和经常以不同的等效方式编码:
或者假设操作
-
(和以前一样)
-
-
-
这样的话
-
是函子在数据类型,
-
是相联的和单作的(关于)作为自然转化,
产生的定义单子更传统地用于范畴理论(即作为幺半对象 在里面 内函子在平原上类别属于数据类型).
直接检查表明不切实际地使…变形-和-通过将操作符表示为以下组合(使用范畴理论-符号,例如“ev”表示评估图):
精致理念:强单子
但事实上函数式程序设计-语言人们通常考虑上述情况的增强版本:
在这些高阶语言中,除了(霍姆-)设置程序/功能也是实际的数据类型函数,即函数类型 ,就以下方面而言范畴语义学是内部hom-对象 在中笛卡尔闭范畴属于数据类型因此,在这些语言中(例如哈斯克尔)的类型给定的绑定操作的数据类型 ,实际上被认为是函数类型/内部hom
(我们使用同源异形的产品内部hom-附加重新识别类型右侧)
这句话(当心)传统上没有很多括号,如下所示:
一般情况下(除了基本地形属于集合),这样一个迭代函数类型/内部hom比相应的平原丰富(当然不同于)hom集合,并相应地定义为“Kleisli三元组”,但绑定操作键入如下内部的方式是更富有的或更强 结构而不是平原单子关于类型的基本范畴:即它是一个浓缩单子或同等地一强单子关于自己-丰富的对称单体闭范畴类型的(莫吉1991§3,参见。Goubault-Larrecq,Lasota&Nowak 2002年,McDermott&Uustalu(2022年)).
在这样一个丰富/强monad,绑定操作定义为以下组合:
特别是,在函数式编程语言喜欢哈斯克尔以这种方式,它们是真正的强健/丰富的单子。
在这种情况下,在大多数默认讨论中对称单体闭范畴类型的假定为笛卡尔闭合(“经典类型”),但在线性类型理论(例如量子计算)它可以是非笛卡尔的(或者两者都是:cf。双闭单体范畴).
然而,关于效应单体的更多结构可在依赖型理论具有类型universes,其中可能会要求monad操作不仅仅是一个内函数上设置属于类型,但一个自同态的类型universe。至少对于幂等单子本案将在反射子宇宙和模态类型理论也许还有其他地方。
进一步想法:Monad模块
在实践中进一步编程:如果程序可能导致外部影响,如在上面,那么人们通常会想要一些手柄这些影响。
这在在上面运行示例例外其整个设计目的通常是在它们出现时进行处理。
自从“处理”-效果应该意味着这些都是用一些实际的纯数据来完成的类型 ,一个-数据类型上的效果处理程序应该主要由以下形式的程序组成
处理由-有效的程序把它们变成纯粹的计算.
但除此之外,这样的处理程序需要处理已经“携带”的效果(2)从以前的计算中,甚至在其他有效的计算中; 因此,所有这些都需要分配处理程序:
在这种效果处理选择中,一致性要求:
-
首先处理之前的所有影响(2)然后通过给定的结果与出租相同通过传递给然后立即处理产生的累积:
-
处理这种微不足道的影响不应该是额外的操作:
(8)
由此类赋值组成的数据结构受这些“法律”的约束Kleisli三代数(例如。乌斯塔鲁(2021),Lec。2)或可拓系统上的代数(请参见在这里)的与传统的范畴理论被称为代数或-代数或者,最好是:-模块或-模态类型.
给定一个一对这样的-模态类型 ,,一个函数是一个同态如果处理结果-使用前后的效果是相同的,因此如果对于所有函数以下内容图表通勤:
免费-效果处理程序。请注意在上面我们已经启动了绑定操作(2)作为一种-效果处理:即作为前一个的“延续”-效果。这种直觉现在变成了一种精确的说法:
对于任何我们可以用重言式处理(8) -通过将其吸收到数据类型中而产生的效果,effecthandler只是effect-binding操作(2):
(9)
这个-效应手(8)以这种方式出现称为自由的.
这个完整子范畴的免费-效果处理程序全部的 -模态类型被称为Kleisli类别.由克莱斯利等价,这是相等的(普通)类别(6)属于-我们开始的有效程序。这意味着:
- 普通数据类型-它们之间的有效程序是等价的数据类型,可以自由地使用-效果处理程序。
这很有道理。
双重理念:共鸣背景
由形式对偶,所有上述讨论都有双重版本,其中现在(例如。乌斯塔卢和维尼(2008),POM13型,GKOBU16号机组,20韩元):
更详细地说:
-
除此之外,我们还有:
-
现在双重地:
-
A类科克莱斯利地图对于余单子 是一个程序
从属于外部-”上下文” (乌斯塔鲁和维尼(2008),POM13型)
(a)-原因).
-
comonad的co-Kleisli co-module是一个程序
生产或提供这样的-上下文。
(参见[乌斯塔卢(2021),勒克特。3,幻灯片9])
句法思想:Do-notation
最后,将所有这些转化为有效的程序设计语言只需声明方便语法用于表示克莱斯利成分.
其中一种语法称为“do表示法“(以”{...}
“而不是”做
“由Launchbury 1993§3.3,然后由提升马克·琼斯20世纪90年代[HHPW07,第25页]并被采纳哈斯克尔在里面版本1.3,请参阅Benton,Hughes&Moggi 2002年第70页,Milewski 2019第20.3条)旨在共同表达:
-
连续的Kleisli作文,比如“做这个,做那个,然后返回结果”,
-
作为“提取”a的任何中间绑定操作-基准中的-基准带符号d<-E
句法上,do-notation如下语法甜头对于组合克莱斯利成分和变量绑定:
-
do程序
掠夺
-
做prog1程序2
prog1绑定(\_->prog2)
-
do(x<-prog1)程序2
prog1绑定(\x->prog2)
首先,这是一个暗示符号(实际上是一个“领域专用嵌入式编程语言“,请参阅那里)用于表达效应结合:
但因此,它还提供了一种方便的方法,通过连续地“调用”单独的过程来简单地表达连续的克莱斯利构图,其风格主要是命令式编程(因此由pure模拟/封装函数式编程):
但符号变得更具启发性,因为“<-
“对于具有微小输入或输出(即单元类型 )除了他们-效果,如本例所示:
这个案例清楚地显示了环境做
…返回
“-syntax块表示任意数量的-有效的程序。
除此之外,“<-
“-语法意在暗示读出一个值。这是准确的图像状态monad(及其对IO-monad公司),其中从读/写全局变量的两个pasic操作
任何-有状态程序,例如简单示例
可以用do-notation构造,例如:
对于类似的效果单体,例如列表单子类似的做
-递增数字列表中所有条目的代码如下所示:
这里是做
-右边的符号唤起了每个步骤一个数字从MyList中“读出”,然后返回其增量-但从语言上看,它隐含了要执行此操作的想法对于所有元素并将所有结果重新编译到输出列表中。
事实上,一般来说,将克莱斯利作文视为“读出”数据是一种误导。Kleisli构图真正的目的是根据具有发电机并根据程序的功能定义程序发电机上,因此对于给定的生成数据:
因此,一元效应绑定操作在概念上更准确(如果可能不那么简洁)的程序语言反映是“对于
…做
“-块:
就这种for-do-notation而言,我们从上面开始的一般情况具有以下语法呈现:
这种语法可能不太简明扼要,但它相当接近于用单数效果编程时实际发生的事情。
例如,上面的计算给定列表中所有数字的操作读入对于
…做
-符号如下:
清楚地表明操作方式已应用对于每个数字建立在里面列表。
(注意:与对于
…做
-中用于循环的符号命令式编程,自功能上这些表示为递归.)
将效果绑定作为对于
…做
-表达在以下语境中变得更加明显下部结构的 键入上下文例如在线性类型理论其中,通过“读取”单数类型的想法<-
“-符号变得更加可疑。
例如,考虑相对单子(这个例子)它发送套到向量空间那是他们的线性跨度:
具有
在这种情况下,传统做
-这种符号表明,给定一个向量,人们可以从中“读出”一个基本元素,这在概念上是没有意义的。
相反,真正发生的是定义线性映射关于配备有线性基础 (字面意思是:一套免费的发电机)定义这个映射就足够了对于每个基本向量-这正是对于
…做
-符号-monad表达:
示例
可定义单子
各种单子可定义的就标准而言定型操作(例如产品类型,函数类型等)。其中包括以下内容(参见。Moggi 1991,实验1.1):
状态单子和随机存取存储器
A类功能程序的输入类型 ,输出类型 和可变状态是一个功能(同构)第页,共页类型 –也称为粉碎机(请参见那里).
在(笛卡尔积 内部hom)-附加(咖喱)这相当于它的辅助,它是类型的函数。这里是操作是单子由上述附加词诱导,后一个函数自然被视为Kleisli类别这个单子。这个单子被称为状态单体类型的可变状态:
可能是单子和受控故障
这个也许是单子是操作。这里的想法是,函数在其中Kleisli类别在原始类别中是形式的函数所以要么返回一个值或者返回单元类型/终端对象 。这自然被解释为“没有返回值”,因此表示“计算失败”。
异常单子和异常处理
(…)异常单子(…)
接续单子和接续通行
这个延续单子在给定类型上行为依据.
(…)
公理单元
编程语言可以“公理化”地提供其他monad,这意味着它们是数据结构键入作为monad,但其实际类型形成、绑定和返回操作是编程环境提供的特殊用途操作。
这包括:
在这种情况下:
工具书类
概述
这个扩展系统-计算机科学中使用的单子的样式表示在以下内容中有简要介绍:
并在中扩展
但与计算无关。
单子作为“计算概念”的最初观察结果是:
-
尤金尼奥·莫吉,计算lambda-calculus和monad,单位:第四届计算机科学逻辑年会论文集(1989) 14-23 [doi:10.1010/LICS.1989.39155]
-
尤金尼奥·莫吉,程序设计语言的抽象视图,LFCS报告ECS-LFCS-90-113(1989)[网状物,pdf格式]
(还考虑单子的变换定义4.0.8)
-
菲利普·沃德勒,理解单子,英寸Lisp和函数编程会议,ACM出版社(1990)[pdf格式,数字对象标识代码:10.1145/91556.91592]
-
尤金尼奥·莫吉,计算和单子的概念信息与计算,931 (1991) [doi:10.1016/0890-5401(91)90052-4,pdf格式]
-
菲利普·沃德勒,函数式编程的本质,POPL’92:编程语言原理(1992)1-14[doi:10.1145/143165.143169,pdf格式]
进一步讨论:
关于莫吉(1991):
原产地方位角对于克莱斯利成分有效程序的数量:
引入单极变压器:
更多(早期)文献如下:
一般来说相对单子:
双重概念计算机科学中的共鸣曲作为模型上下文:
关于辅音上下文的尾标法:
并强调将单子,共鸣曲和分级模式:
识别(协同)效应处理(有限公司)模型在给定(co)单子上:
实际讨论程序设计语言例如哈斯克尔:
和斯卡拉:
进一步讨论/阐述计算机科学中(co)单子的概念和应用:
-
斯蒂芬·布鲁克斯、Shai Geva、,计算连词和内涵语义,CMU-CS-91-190(1991)[pdf格式]
-
菲利普·沃德勒,函数编程的单子函数,摘自M.Broy(编辑)程序设计计算北约ASI系列,118斯普林格(1992)[doi;10.1007/978-3-662-02880-3_8,pdf格式]
-
菲利普·穆里,语义学中的单数、ENTCS14(1998)第275-286页。
-
斯蒂芬·布鲁克斯,凯瑟琳·范·斯通,内涵语义学中的单数和连词(1993) [dtic:ADA266522,pdf格式,pdf格式]
(带有分配定律单声道上的共鸣曲)
-
约翰·休斯,第2节:将单数归纳为箭头《计算机编程科学》(Elsevier)37(1-3):67–111。(2000) (pdf格式)
-
罗伯·哈波,当然,ML有单子!(2011) (网状物)
-
尼克·本顿,分类单子与计算机程序设计,单位:影响150:数学影响的故事伦敦数学学会(2015)[pdf格式,pdf格式,doi:10.1112/i150lms/t.0002文件]
-
艾米丽·里尔,计算效果的分类视图,在C类mp(最大功率)东南方会议(2017) [pdf格式,pdf格式]
-
罗布·诺里斯,带效果的函数式编程,在2018年Scala日[视频:年初至今]
-
塔尔莫·乌斯塔卢,课堂讲稿MGS 2021公司(2021):
单子与互动讲座1[pdf格式,pdf格式]
单子与互动讲座2[pdf格式,pdf格式]
单子与互动讲座3[pdf格式,pdf格式]
单子与互动讲座4[pdf格式,pdf格式]
-
克莉丝汀娜·科尔、克莉丝蒂娜·施瓦格、,计算机科学单子(2021) [pdf格式,pdf格式]
另请参阅:
规范单子在里面哈斯克尔位于:
并对范畴理论哈斯克尔的单子
关于CS-型单子真正存在的问题强单子:
单子体与应用函子(也称为习语)和箭头(计算机科学)在中
在量子计算中
讨论量子计算就单子而言:
这个量子IO单子:
展览会:
在中的实现哈斯克尔:
上面条目中的大部分文本和图表如下