2
我正在参加Coursera课程的函数式编程课程,并且在某些时候他们讨论了按值分类和按名称评估技术之间的区别。他们的一些点混淆了我,他们说:按价值和按名称等值
这两种技术都降低到相同的最终值,只要:
- 减少的表达由纯函数和
- 既评估终止
这似乎是一个演算定理。
你能解释一下“纯粹函数的简化表达式”是什么意思吗?
我正在参加Coursera课程的函数式编程课程,并且在某些时候他们讨论了按值分类和按名称评估技术之间的区别。他们的一些点混淆了我,他们说:按价值和按名称等值
这两种技术都降低到相同的最终值,只要:
- 减少的表达由纯函数和
- 既评估终止
这似乎是一个演算定理。
你能解释一下“纯粹函数的简化表达式”是什么意思吗?
纯函数是一个没有副作用的函数(比如执行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
变量的值都会更改。
你有看过https://en.wikipedia.org/wiki/Pure_function? – Bergi
其他学习资料中有相当多的参考资料。最好先检查他们或使用课程论坛。 – Pavel
@Rodrigo这是[Church-Rosser定理](https://en.wikipedia.org/wiki/Church%E2%80%93Rosser_theorem)的非正式声明,lambda微积分是通过这种非正式声明汇合的。您所指的短语可能仅存在于此,因为使用Scala定理只是对术语的轻微滥用,因为它仅适用于该语言的某个纯粹的子集。 – phg