“ monad是计算模型”是什么意思

时间:2019-05-07 15:35:38

标签: haskell monads category-theory

当人们说“ monad是计算模型”时,这到底是什么意思?从完整性的意义上讲,这意味着计算吗?如果可以,怎么办?

澄清:这个问题不是要解释单子,而是人们在这种情况下对“计算模型”的含义以及它与单子的关系。请参见this answer的结尾以获取该词组的典型用法。

在我对图灵机的理解中,递归函数,lambda微积分等理论都是计算模型,我完全看不出monad与该模型有何关系。

3 个答案:

答案 0 :(得分:14)

单子作为计算模型的思想可以追溯到Eugenio Moggi的工作。在Haskell的从业者中,Moggi对此问题最著名的论文是Notions of computations as monads(1991)。相关报价包括:

  

λ演算被认为是编程语言研究中的一种有用的数学工具,因为可以使用λ项对程序进行识别。但是,如果走得更远并且使用βη转换来证明程序的等价性,则会引入总体简化(程序从 values values < / em>),这可能会损害理论结果的适用性,在本文中,我们将基于计算的分类语义引入计算,这将为证明程序的等效性提供正确的基础, em>计算概念。 [p。 1]

     

[...]

     

我们并不是以证明程序等效的出发点为基础的βη转换理论,该理论确定了类型A-> B的程序(过程)的含义,其总功能来自A对于B,由于此标识完全消除了可以由实际程序表现出的行为,例如非终止,不确定性和副作用。相反,我们按以下步骤进行操作:

     
      
    1.   
    2. 我们将范畴论作为函数的一般理论,并在此基础上发展了基于单子的计算的范畴语义。 [...] [p。 1]
    3.   
  •   
     

[...]

     

下面的类别语义背后的基本思想是,为了解释类别[C]中的编程语言,我们将值的对象A(类型A)与计算的对象TA(类型A)区分开来),并将TA的元素作为程序的表示形式(类型A)。特别地,我们通过将值对象(类型A)识别为类型A,并通过将一元类型构造函数T应用于A来获得计算对象(类型A)。我们将T a 计算概念称为,因为它抽象了可能产生的值的类型。对应于不同计算概念的TA有很多选择。 [pp。 2-3]

     

[...]

     

我们已经确定了monad对计算概念建模非常重要,但是计算monad 似乎还具有其他属性;例如,它们具有抗张强度并且可以满足单声道要求。可能还有待确定的计算单核的其他性质,并且没有理由认为必须在有关单核的文献中找到这些性质。 [p。 27-谢谢danidiaz]

Moggi的一篇相关的较早论文,Computational lambda-calculus and monads(1989年,感谢米奇德作参考),从字面上讲是“计算模型”:

  

计算模型是满足 mono要求的单子(T;η;μ):[eta-A]是每个A的单声道[属于] C。

     

还有一个有关monad的替代描述(请参阅[7]),它更容易通过计算证明。 [...] [p。 2]

随着Moggi将演讲的重点放在“替代性描述”(即Kleisli三元组,由以下组成:用Haskell的话来说,是类型构造函数,返回并绑定)。但是,本质在整个过程中都保持不变。


Philip Wadler在Monads for functional programming(1992)中更实际地提出了这个想法:

  

描述了使用monad构建功能程序的方法。 Monads提供了一个方便的框架来模拟在其他语言中发现的效果,例如全局状态,异常处理,输出或不确定性。 [p。 1]

     

[...]

     

纯功能语言具有此优点:所有数据流都是显式的。而缺点是:有时是痛苦的显式。

     

纯功能语言的程序被编写为一组方程。显式数据流可确保表达式的值仅取决于其自由变量。因此,用equals代替equals总是有效的,这使得此类程序尤其容易推理。明确的数据流还可以确保计算顺序无关紧要,从而使此类程序容易受到延迟评估的影响。

     

就模块化而言,明确的数据流既是福也是祸。一方面,它是模块化的终极目标。所有的数据输入和输出的数据都将显示出来并可以访问,从而提供最大的灵活性。另一方面,它是模块化的最低点。从本质上讲,算法的本质可以掩盖在从创建点到使用点的数据传输所需的管道之下。 [p。 2]

     

[...]

     

说,希望添加错误检查,以便上面的第二个示例返回明智的错误消息。在不纯洁的语言中,使用异常很容易实现。

     

在纯语言中,可以通过引入类型来表示可能引发异常的计算来模仿异常处理。 [pp。 3 -4-请注意,这是在将monad作为统一抽象引入之前的。]

     

[...]

     

解释器上的每个变体都有相似的结构,可以对其进行抽象化以产生单子的概念。

     

在每个变体中,我们引入了一种计算类型。 M分别表示可能引发异常,作用于状态并生成输出的计算。到现在为止,读者可能已经猜到M代表monad。 [p。 6]

这是使用“计算”​​来指代单子数值的根源之一。


后来的大量文献以这种方式利用了计算的概念。例如,这是Exequiel Rivas和Mauro Jaskelioff的Notions of Computation as Monoids的开场白(2014年-感谢danidiaz的建议):

  

在构造系统的语义模型或​​构造计算机代码时,可能会考虑几种计算概念。 Monads(Moggi,1989; Moggi,1991)是最流行的概念,但其他概念,例如箭头(Hughes,2000),以及最近的应用函子(McBride&Paterson,2008)已被广泛接受。这些计算概念中的每一个都有特定的特征,这使它们更适合于某些任务而不是其他任务。尽管如此,将所有三个不同的概念统一在一个概念框架中将有很多收获。 [p。 1]

另一个很好的例子是Tarmo Uustalu和Varmo Vene(2000)的Comonadic notions of computation

  

自从80年代末Moggi开创性的工作以来,单子(更确切地说是强壮的单子)已成为公认的用于构建有效的计算概念的工具,例如,异常计算,输出,使用环境的计算,状态-想法是使用Kleisli类别作为不纯的,有效函数的类别,其中Kleisli包含项将基础类别的纯函数嵌入。 [...] [p。 263]

     

[...]

     

单值方法(按值调用)有效计算的出发点是这样的想法,即从A到B的不纯的,有效的功能一定不是从A到TB的纯功能。在这里,纯函数位于基本类别C中,T是C的内隐函数,描述了感兴趣效应的概念;将TA视为对给定类型A的值进行有效计算的一种类型。

     

要使此功能起作用,不纯功能必须具有标识并组成。因此,T不仅可以是函子,还必须是单子。 [p。 265]


“计算”的这种用法符合models of computation的通常计算机科学概念(有关更多信息,请参见danidiaz's answer)。在非正式函数式编程文献中,对单子词的暗示作为计算模型具有不同程度的精度。尽管如此,它们通常还是来自一个严格的想法,或者至少是一个严格的想法的分支。

答案 1 :(得分:12)

什么都没有。没什么意思这是某人努力寻找隐喻的结果,这些隐喻使单子变成了他们已经知道的东西。这几乎是什么意思。例如,“可以构建形成单子的计算模型”是有意义的陈述。但是差异很大。 “ Monad是计算模型”是试图将广泛的抽象转化为狭义的解释。另一个指定您可以为一个用例使用更广泛的抽象。

非常警惕还原性的解释。您是否认为,如果熟悉的术语传达相同的信息,那么整个开发人员社区都会继续使用陌生的术语吗? Monad一词在一个语言社区中已经存在了20年,该社区在寻求改进的同时迅速发明并放弃了抽象。唯一可能发生的方法就是传达一些有用且精确的信息。

很难写出这种想法在编程中的应用的解释,这对于那些对语言了解不足以理解所使用的构造的人来说毫无意义。如果您不满意至少具有较高类型的类型,类型类和高阶函数,则无法理解该符号的含义。

学习先决条件将有所帮助。练习编写代码会有所帮助。研究(>>=)对于各种具体类型的工作方式将有所帮助。努力学习如何使用像Parsec这样的库(或像megaparsec这样的现代后代)会有所帮助。

试图强迫这个想法与通过隐喻已经知道的东西相匹配就不会了。

答案 2 :(得分:4)

在@duplode的答案上稍加扩展,我认为在谈论计算时,“模型”至少可以具有两种略有不同的含义。


model的意义上,一个是Church–Turing thesis。在这里,模型是一种能够表达任何算法的执行计算的方式。所以turing machineslambda calculuspost correspondence systems ...都是模型。


另一个是programming language semantics意义上的模型。我们的想法是,我们将程序视为可组合的语法结构,并且希望它们“表示”某种东西,理想情况下,这种方式可以让我们根据元素的含义确定组合的含义。从这个意义上讲,lambda演算具有模型。

现在,一种语义是denotational semantics,其中我们分配给程序的含义是某种数学对象。举一个简单的例子,考虑二进制数。这里的“程序”是0和1的字符串,被视为纯符号。而且“模型”将是自然数,以及一个将符号的每个字符串映射到相应自然数的函数。

有时,这些程序表示法用category theory表示。这就是Moggi论文的背景:他正在利用类别理论(如monad)中的机制将编程语言概念(如异常,延续,输入/输出...)映射到数学模型中。 Monad成为构建程序含义的数学世界的便捷方法。