如何判断F#函数是否纯粹?

时间:2013-04-08 17:09:38

标签: f# pure-function

假设我有两个F#函数:

let sq x = x*x

let tm = DateTime.Now

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

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

或者有一种方法可以注释一个函数,以便在编写函数时告诉编译器该函数是纯函数还是不纯函数?

最后,当调用一个属于公共语言运行库的函数(例如DateTime)时,如果不尝试它就可以判断它是纯粹的还是不纯的?

注意:"纯"我的意思是维基百科的定义:http://en.wikipedia.org/wiki/Pure_functionpermalink

  

在计算机编程中,如果两者兼有,则可以将函数描述为纯函数   关于函数的这些陈述持有:

     
      
  1. 该函数始终在给定相同参数的情况下计算相同的结果值   值(S)。功能结果值不能依赖于任何   可能随程序执行而变化的隐藏信息或状态   继续或在程序的不同执行之间,也不可能   取决于I / O设备的任何外部输入。

  2.   
  3. 评估结果不会导致任何语义上可观察的一面   效果或输出,例如可变对象的变异   或输出到I / O设备。

  4.   

3 个答案:

答案 0 :(得分:9)

F#没有提供任何检查方法是纯粹的功能和工具,所以一个简单的答案就是你必须自己检查这个属性。

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

答案 1 :(得分:1)

从技术上讲,你的'tm'值不是一个函数,而是DateTime类型的值,它是不可变的,所以每次在创建它之后评估这个值都将是相同的。

答案 2 :(得分:0)

鉴于可以在f#中定义纯函数和纯函数,如果有一个算法可以检查f#代码(函数定义)的纯度,我会很惊讶 - 检查程序代码的语义属性一般莱斯定理不可判定。