Functional programming 纯函数式语言中副作用的可能方法

Functional programming 纯函数式语言中副作用的可能方法,functional-programming,Functional Programming,我想知道函数式语言中所有可能产生副作用的方法,即使是理论上的,也没有在实践中使用 我知道monad(Haskell)和惟一性类型(Clean)。还有其他可能性吗?具有强纯函数和弱纯函数。强纯函数在许多方面与Haskell中得到的函数相似。另一方面,弱纯函数可以改变它们的参数,但不能改变全局状态。其思想是,pure和pure一样:函数的私有状态被扩展为允许函数在不改变全局状态的情况下改变其私有状态。在默认情况下,一切都是纯的(即使是IO),如果不使用很少需要的特性,就不可能编写不纯净的代码 纯IO

我想知道函数式语言中所有可能产生副作用的方法,即使是理论上的,也没有在实践中使用

我知道monad(Haskell)和惟一性类型(Clean)。还有其他可能性吗?

具有强纯函数和弱纯函数。强纯函数在许多方面与Haskell中得到的函数相似。另一方面,弱纯函数可以改变它们的参数,但不能改变全局状态。其思想是,pure和pure一样:函数的私有状态被扩展为允许函数在不改变全局状态的情况下改变其私有状态。

在默认情况下,一切都是纯的(即使是IO),如果不使用很少需要的特性,就不可能编写不纯净的代码

纯IO的处理方式与Clean(我相信)类似,使用唯一性和世界状态参数。Mercury认为唯一性是一种模式属性,而不是类型属性。(本文中的“模式”或多或少是数据流方向)

但汞也有一个静态纯度系统。有些代码被编译器识别为不纯净(调用外语接口,或调用已知的不纯净函数/谓词,访问可变变量,以及其他一些情况)。此类代码必须明确声明为不纯,否则是编译器错误。因为编译器知道不纯净的代码,所以它不会执行可能影响不纯净代码的重新排序或其他优化。如果在某种程度上,您可以围绕不纯操作提供纯接口,那么您可以向编译器保证函数/谓词实际上是纯的。否则,所需的杂质声明会一直传播到
main
谓词;如果你准备这么做的话,你基本上可以在Mercury中进行必要的编程(尽管这并不有趣)


Mercury也有半纯代码的概念。这是一种不会对任何其他半纯或不纯代码的操作产生副作用的代码(根据定义,纯代码不受任何其他代码副作用的影响),但可能会受到其他不纯代码副作用的影响。这种额外的信息水平意味着,编译器仍然可以更自由地优化那些不纯粹的调用,因为它们“看到”了副作用,但本身没有副作用;如果不需要它们的结果,则可以对它们进行优化,并且只要它们没有在不纯净的调用上“移动”,就可以重新排序。

Haskell用于将I/O状态视为一对无限流。作为一个例子(大大简化),您的主函数接受一个参数,它是一个响应流,并生成一个结果,它是一个请求流。在输出流中“发出”请求之后,相应的响应将在流中相同位置的输入流中可用。这仍然是功能性的,因为Haskell中的流只是数据结构,所以您可以始终访问旧的响应。给出了更好的描述

另一个存在的范例是函数式反应式编程。FRP引入了一种称为行为的特殊类型的值,其值反映了“真实世界”(磁盘上的文件、鼠标位置等)中某些对象的当前值。输入行为可以以功能性的方式相互组合以产生输出行为,实现使用这些行为来更新“真实世界”(例如,显示内容)中的内容。大多数FRP实现还引入了第二种特殊类型的值,称为事件,相当于仅在离散时间点(如按键或鼠标单击)具有值的行为,并提供了库函数,用于以有用的方式组合行为和事件(最重要的是“记忆”)过去某个事件发生时某个行为的值)

我想知道函数式语言中所有可能产生副作用的方法,即使是理论上的,也没有在实践中使用。[...] 还有其他的可能性吗

当然-这是我在这里和那里挖掘到的,大部分来自网络空间。一些初始点:

  • 接下来的大部分内容涉及扩展或更改,因为这是非严格的,与传统的副作用处理方法相冲突;有关更多详细信息,请参见的第2.1节(第12-2页)、第3.1节和第3.2节(第12-8页)。(提示:完整的文档也有助于阅读。)

  • 同样,I/O在Haskell副作用的早期研究中占据主导地位(一元I/O仅在Haskell 1.3中正式出现)。有了新的见解和一些工作,长期处于休眠状态的想法通常可以重新应用到其他地方

  • 由于这些方法中有些似乎没有,所以有一些“临时命名”

  • 这些就是我所知道的可以在函数式语言中使用的方法。如果您愿意研究支持其他编程范式的语言(例如,or中的逻辑),您可以找到其他方法。如需灵感,请参阅Pieter Hartel和Willem Vree的作品

因此,除了其他答案中提到的方法外,还有:

  • 继续-有关快速介绍,请参见Denys Duchier。Haskell的早期版本将此方法用作基于流的I/O的替代方法-请参阅的第7.1节(第12-22页)。Philip Wadler将其与中的一些其他方法联系起来(第18页第3.2节)

    最近的申请可以在李鹏和史蒂夫·兹丹切维奇的(第6页第3.3节)中看到

    从通用Lisp到VisualBasic,互联网上还有一半关于如何使用这些语言的信息——只要启动你最喜欢的搜索引擎就可以了

  • “正交指令”——见Maarten Fokkinga和Jan Kuper

  • 伪数据-见F.Warren Burton。一 可以吗