纯函数是那些在每次调用时返回相同值并且没有副作用的函数。
引用透明性意味着您可以将绑定变量替换为其值,并且仍会收到相同的输出。
纯粹的和引用透明的:
def f1(x):
t1 = 3 * x
t2 = 6
return t1 + t2
为什么这是纯净的?
因为它只是输入的函数,x没有副作用。
为什么这是引用透明的?
您可以在语句中用它们各自的右侧替换t1and t2in ,如下所示f1return
def f2(x):
return 3 * x + 6
并且f2仍将始终返回与f1每种情况相同的结果。
纯粹的,但不是引用透明的:
我们修改f1如下:
def f3(x):
t1 = 3 * x
t2 = 6
x = 10
return t1 + t2
让我们再次尝试同样的技巧,将t1和替换t2为它们的右手边,看看它是否是 的等价定义f3。
def f4(x):
x = 10
return 3 * x + 6
我们可以很容易地观察到这一点,f3并且f4在用右手边/值替换变量时并不等同。f3(1)将返回9并将f4(1)返回36。
引用透明,但不纯:
只需修改f1以接收 的非本地值x,如下所示:
def f5:
global x
t1 = 3 * x
t2 = 6
return t1 + t2
执行与之前相同的替换练习表明f5仍然具有引用透明性。但是,它不是纯粹的,因为它不仅仅是传递给它的参数的函数。
仔细观察,我们失去从f3到的引用透明度的原因f4是它x被修改了。在一般情况下,创建一个变量final(或者那些熟悉 Scala 的人,使用vals 而不是vars)并使用不可变对象可以帮助保持函数的引用透明。这使它们更像是代数或数学意义上的变量,从而更好地进行形式验证。