2

我正在参加Coursera课程的函数式编程课程,并且在某些时候他们讨论了按值分类和按名称评估技术之间的区别。他们的一些点混淆了我,他们说:按价值和按名称等值

这两种技术都降低到相同的最终值,只要:

  1. 减少的表达由纯函数和
  2. 既评估终止

这似乎是一个演算定理。

你能解释一下“纯粹函数的简化表达式”是什么意思吗?

+2

你有看过https://en.wikipedia.org/wiki/Pure_function? – Bergi

+0

其他学习资料中有相当多的参考资料。最好先检查他们或使用课程论坛。 – Pavel

+1

@Rodrigo这是[Church-Rosser定理](https://en.wikipedia.org/wiki/Church%E2%80%93Rosser_theorem)的非正式声明,lambda微积分是通过这种非正式声明汇合的。您所指的短语可能仅存在于此,因为使用Scala定理只是对术语的轻微滥用,因为它仅适用于该语言的某个纯粹的子集。 – phg

回答

4

纯函数是一个没有副作用的函数(比如执行IO或更改任何非本地函数的值)。一个纯函数的一个例子是:

def inc(x: Int) = x+1 

的非纯函数的一个例子是:

var sum = 1 
def addToSum(x: Int) = { 
    sum += x 
    sum 
} 

所以,现在让我们考虑以下两种方法,无论他们把他们的论点只相差按名称或值:

def doubleByValue(x: Int) = x + x 
def doubleByName(x: =>Int) = x + x 

现在,如果我们使用这两种与纯函数,结果是一样的:

doubleByValue(inc(2)) // => 6 
doubleByName(inc(2)) // => 6 

但是,如果我们把它们应用到非纯函数,结果不同:

sum = 1 // Let's reset sum, so the result isn't affected by previous uses 
doubleByValue(addToSum(2)) // => 6, the value of `sum` is now 3 
sum = 1 // Let's reset sum, so the result isn't affected by previous uses 
doubleByName(addToSum(2)) // => 8, the value of `sum` is now 5 

的区别在于,ByName版本调用函数两次,并增加了两个结果,而ByValue版本调用一次,保存结果并将其添加到自身。

对于纯函数,这完全没有区别 - 给定相同的参数,它将始终返回相同的结果,因此,无论您调用一次并使用保存的结果两次还是将其调用两次(除外表现)。

对于不纯功能,它会产生很大的差异,因为每次调用函数时,sum变量的值都会更改。