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

时间:2011-12-29 10:24:26

标签: functional-programming

我想知道功能语言中所有可能的副作用方法,甚至是理论上的,也没有在实践中使用。

我了解Monads(Haskell)和Uniqueness类型(Clean)。还有其他可能性吗?

4 个答案:

答案 0 :(得分:6)

Mercury中,默认情况下(即使是IO)一切都是纯粹的,并且在不使用很少需要的功能的情况下编写不纯的代码是不可能的。

通过使用唯一性和世界状态参数,以类似于Clean(我相信)的方式处理Pure IO。 Mercury认为唯一性是模式属性,而不是类型属性。 (此上下文中的“模式”或多或少是数据流方向)

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

Mercury还有 semipure 代码的概念。这是对任何其他半成品或不纯代码的操作没有副作用的代码(根据定义纯代码不受任何其他代码的副作用的影响),但可能副作用的影响其他不纯的代码。这种额外的信息水平意味着那些只是不纯的调用,因为它们“看到”副作用但没有任何自身的调用仍然可以被编译器更自由地优化;如果不需要他们的结果,他们可以被优化掉,只要他们没有被impure电话“移动”,他们就可以重新排序。

答案 1 :(得分:2)

D programming language具有纯函数和纯函数。强大的纯函数在很多方面与Haskell中的函数类似。另一方面,弱纯函数可以改变它们的论点,但它们不能改变全局状态。这个想法是 pure就像纯粹的:函数的私有状态被扩展为允许在不改变全局状态的情况下改变其私有状态的函数。

答案 2 :(得分:2)

Haskell曾经将I / O状态视为一对无限流。作为一个例子(大大简化),你的main函数接受了一个参数,它是一个响应流,并产生一个结果,这是一个请求流。在输出流中“发出”请求之后,相应的响应将在流中相同位置的输入流中可用。这仍然有用,因为Haskell中的流只是数据结构,因此您始终可以访问旧响应。 This paper提供了更好的说明。

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

答案 3 :(得分:1)

我想知道功能语言中所有可能的副作用方式,甚至是理论上的但实际上没有使用。 [...] 还有其他可能性吗?

当然-这就是我在这里和那里挖来的东西,主要是从网络空间中挖掘出来的。一些初始点:

  • 随后的大多数事情涉及Haskell的扩展或更改,因为它是非严格的,这与传统的副作用处理方法相冲突;有关更多详细信息,请参见A History of Haskell的2.1(第12-2页),3.1和3.2(第12-8页)部分。 (提示:完整的文档也便于阅读。)

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

  • 由于其中一些方法似乎没有,因此有一些“即兴名称”

  • 这些只是我所知道的可以在功能语言中使用的方法。如果愿意查看支持其他编程范例的语言(例如MercuryProlog中的逻辑),则可以找到其他方法。要获取灵感,请参见Pieter Hartel和Willem Vree的Lambda Calculus for Engineers

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

  • 继续-有关快速介绍,请参见Denys Duchier的Continuations Made Simple and Illustrated。 Haskell的早期版本使用此方法替代基于流的I / O-请参阅A History of Haskell的7.1节(第12-22页)。 Philip Wadler将其与How to Declare an Imperative(第18页的第3.2节)中的其他一些方法相关联。

    Peng Li和Steve Zdancewic的A Language-based Approach to Unifying Events and Threads(第6页的第3.3节)中提供了最新的应用程序。

    Internet上还有一半的信息可供您使用从Common Lisp到Visual Basic的各种语言来完成操作-只需启动您喜欢的搜索引擎即可。

  • “正交指令” -参见Maarten Fokkinga和Jan Kuper的An alternative approach to I/O

  • “具有效果的数据结构” -John Launchbury和Simon Peyton Jones在early example中找到了State in HaskellHackage还揭示了一些库实现。参考:

    L。 Augustsson,M。Rittri和D.Synek。关于生成唯一名称。 J.Functional Programming,1994年1月,4(1):117-123。

  • 系统令牌-除原始备忘外,很少有其他细节:

    L。奥古斯特森。使用系统令牌的功能性I / O。查尔默斯理工大学计算机科学系PMG Memo 72,S-412 96,哥德堡,1989年。

  • 证人-参见Tachio Terauchi和Alex Aiken的Witnessing Side Effects

  • 观察者-参见Vipin Swarup,Uday S. Reddy和Evan Ireland的Assignments for Applicative Languages

  • “效果树” -除了实际文件外,没有太多信息:

    Rebelsky S.A.(1992)I / O树和交互式惰性函数编程。在:Bruynooghe M.,Wirsing M.(eds)编程语言实现和逻辑编程中。 PLILP1992。计算机科学讲义,第631卷。施普林格,柏林,海德堡。

现在我要做一些自己的工作:最近,我已经在GHC中测试了基于“具有效果的数据结构” 的抽象,以提供新鲜的名称和I / O,已经使用在一个用于该项目和基本异常处理的较小项目中-如果您感兴趣,我为GHC 8.6.5版本整理了一些patches