我对纯函数有疑问。根据Wikipedia页面,纯功能的必要条件之一是:
结果评估不会引起任何语义上可观察到的副作用或输出,例如可变对象的突变或输出到I / O设备。
现在这到底是什么意思。或者更确切地说,我该如何做一个语义上无法观察到的副作用?
我对纯函数有疑问。根据Wikipedia页面,纯功能的必要条件之一是:
结果评估不会引起任何语义上可观察到的副作用或输出,例如可变对象的突变或输出到I / O设备。
现在这到底是什么意思。或者更确切地说,我该如何做一个语义上无法观察到的副作用?
Answers:
程序的语义是其行为的模型,它像任何科学模型一样,会忽略您不想学习的方面。
程序执行的极其详细的模型将对执行该程序的计算机的物理行为进行建模,包括执行时间,功耗,电磁辐射等。这些方面很少考虑,因为它们很少相关。尽管如此,它们有时还是很重要:飞机自动驾驶仪的有用模型需要包括运行时信息,信用卡安全性的有用模型需要包括电磁辐射,...
在典型的语义中,诸如时序和功耗之类的副作用被忽略。即使在平凡的设置中(在Haskell解释器提示下键入表达式),结果的打印也有副作用(如果您尝试打印出无限大的对象,这很重要)。如果Haskell解释器的内存不足,这在“现实世界”模型中也是可观察到的副作用,但在有效允许无限计算的Haskell理想模型中却不是。
一个可观察到的副作用是一个其在语义建模。在典型的编程语言模型中,不对内存消耗进行建模,因此,即使您尝试在PC上运行它,也需要1TB存储空间的计算可能是纯净的。
另一种不可观察到的副作用是该功能内部的副作用。我认为,这就是大多数语义学家在谈论不可观察到的副作用时会想到的。考虑一个在内部使用可变数据但不与程序的任何其他部分共享此可变数据的计算。例如,一个列表排序函数可以构建一个与列表具有相同元素的数组,对数组进行排序,然后以最终顺序返回一个包含元素作为数组的列表:该函数的子表达式语义模型表现出优势效果(数组的修改),但函数本身没有外部副作用,因此是纯函数。
举一个更微妙的例子,考虑一个函数,该函数将一些数据写入一个临时文件,然后对其进行清除。在语义上,总是有足够的空间容纳临时文件,而程序不共享临时文件,因此该函数没有副作用。临时文件充当该功能使用的额外内存。在考虑了文件系统完整条件的语义中,该函数具有副作用-由于外部环境,它可能会失败。在允许机器崩溃的语义中,该函数具有副作用:如果在函数执行期间发生崩溃,则可能会留下临时文件。在允许同时执行的程序查看并可能修改临时文件的语义中,该函数具有副作用。