8

假设我有这两个 F# 函数:

let sq x = x*x

let tm = DateTime.Now

显然 sq 是纯的,因为它总是为给定的输入返回相同的值,而 tm 是不纯的,因为每次调用它都会返回不同的值。

一般来说,有没有一种方法可以确定 F# 中的特定函数是纯函数还是不纯函数,而无需分析它的作用,换句话说,就是逐行读取它?

或者,有没有办法在编写函数时注释函数以告诉编译器该函数是纯函数还是不纯函数?

最后,当调用作为公共语言运行时一部分的函数(例如 DateTime)时,如何不尝试就判断它是纯函数还是不纯函数?

注意:“纯”是指来自维基百科的定义:http ://en.wikipedia.org/wiki/Pure_function (永久链接

在计算机编程中,如果关于函数的以下两个陈述都成立,则可以将函数描述为纯函数:

  1. 给定相同的参数值,该函数始终评估相同的结果值。函数结果值不能依赖于任何可能随着程序执行或程序的不同执行而改变的隐藏信息或状态,也不能依赖于来自 I/O 设备的任何外部输入。

  2. 结果的评估不会导致任何语义上可观察的副作用或输出,例如可变对象的突变或输出到 I/O 设备。

4

3 回答 3

9

F# 没有提供任何功能和工具来检查方法是否纯,因此一个简单的答案是您必须自己检查此属性。

在 F# 之外,值得注意的是Code Contracts库有一个纯方法的概念(它们可以用 标记PureAttribute),但我不完全确定那里的检查故事是什么。我认为 Code Contracts 带有分析 IL 的静态检查器(也应该适用于 F#),但这是一项非常艰巨的任务,所以我希望它非常有限。但是,PureAttribute在某些 BCL 方法上使用了 ,因此您可以看出某些标准 .NET 方法是纯的。

于 2013-04-08T17:48:01.890 回答
1

从技术上讲,您的 'tm' 值不是函数,而是 DateTime 类型的值,并且它是不可变的,因此每次在创建后评估此值时总是相同的。

于 2013-04-08T19:40:20.160 回答
-1

鉴于可以在 f# 中定义纯函数和非纯函数,如果有一种算法可以检查 f# 代码(函数定义)的纯度,我会感到非常惊讶——检查程序代码的语义属性通常无法由 Rice 的定理。

于 2013-04-09T11:52:23.443 回答