假设我有两个F#函数:
let sq x = x*x
let tm = DateTime.Now
显然sq是纯粹的,因为它总是会返回给定输入的相同值,而tm是不纯的,因为每次调用它时都会返回不同的值。
一般来说,有一种方法可以确定F#中的特定函数是纯粹的还是不纯的而不分析它的作用,换句话说就是逐行读取它?
或者有一种方法可以注释一个函数,以便在编写函数时告诉编译器该函数是纯函数还是不纯函数?
最后,当调用一个属于公共语言运行库的函数(例如DateTime)时,如果不尝试它就可以判断它是纯粹的还是不纯的?
注意:"纯"我的意思是维基百科的定义:http://en.wikipedia.org/wiki/Pure_function(permalink)
在计算机编程中,如果两者兼有,则可以将函数描述为纯函数 关于函数的这些陈述持有:
该函数始终在给定相同参数的情况下计算相同的结果值 值(S)。功能结果值不能依赖于任何 可能随程序执行而变化的隐藏信息或状态 继续或在程序的不同执行之间,也不可能 取决于I / O设备的任何外部输入。
- 醇>
评估结果不会导致任何语义上可观察的一面 效果或输出,例如可变对象的变异 或输出到I / O设备。
答案 0 :(得分:9)
F#没有提供任何检查方法是纯粹的功能和工具,所以一个简单的答案就是你必须自己检查这个属性。
在F#之外,值得注意的是Code Contracts库有一个纯方法的概念(它们可以用PureAttribute
标记),但我不完全确定什么是检查故事那里。我认为代码契约带有静态检查器来分析IL(也应该适用于F#),但这是一项非常困难的任务,所以我希望它非常有限。但是,PureAttribute
用于某些BCL方法,因此您可以判断一些标准的.NET方法是纯粹的。
答案 1 :(得分:1)
从技术上讲,你的'tm'值不是一个函数,而是DateTime类型的值,它是不可变的,所以每次在创建它之后评估这个值都将是相同的。
答案 2 :(得分:0)
鉴于可以在f#中定义纯函数和纯函数,如果有一个算法可以检查f#代码(函数定义)的纯度,我会很惊讶 - 检查程序代码的语义属性一般莱斯定理不可判定。