假设我有这两个F#函数:
let sq x = x*x
let tm = DateTime.Now
Run Code Online (Sandbox Code Playgroud)
显然sq是纯粹的,因为它总是返回给定输入的相同值,而tm是不纯的,因为每次调用它时它将返回不同的值.
通常有一种方法可以确定F#中的特定函数是纯粹还是不纯,而不分析它的作用,换句话说,逐行读取它?
或者是否有一种方法来注释一个函数,告诉编译器在编写函数时该函数是纯函数还是不纯函数?
最后,当调用作为公共语言运行库(如DateTime)一部分的函数时,如何在不尝试的情况下判断它是纯粹的还是不纯的?
注意:"纯"是指维基百科的定义:http://en.wikipedia.org/wiki/Pure_function(permalink)
在计算机编程中,如果关于函数的这两个语句都成立,则函数可以被描述为纯函数:
在给定相同参数值的情况下,该函数始终评估相同的结果值.函数结果值不能依赖于程序执行过程中或程序的不同执行之间可能发生变化的任何隐藏信息或状态,也不依赖于来自I/O设备的任何外部输入.
对结果的评估不会导致任何语义上可观察到的副作用或输出,例如可变对象的突变或输出到I/O设备.
F#没有提供任何检查方法是纯粹的功能和工具,所以一个简单的答案是你必须自己检查这个属性.
在F#之外,值得注意的是Code Contracts库有一个纯方法的概念(并且它们可以标记PureAttribute
),但我不完全确定那里的检查故事是什么.我认为代码契约带有静态检查器来分析IL(也应该适用于F#),但这是一项非常困难的任务,所以我希望它非常有限.但是,它PureAttribute
被用于某些BCL方法,因此您可以看出一些标准的.NET方法是纯粹的.