gpt4 book ai didi

scala - Scala 中类方法和闭包上下文中的纯函数

转载 作者:行者123 更新时间:2023-12-02 04:11:43 24 4
gpt4 key购买 nike

Scala中纯函数的精确定义是什么?纯函数有一个定义,在 wiki https://en.wikipedia.org/wiki/Pure_function 。我认为这个定义是针对纯函数式编程语言的。

但是,我认为在类方法和闭包的上下文中它会变得复杂。

class Ave(val a: Int, val b: Int) {
def ave = (a+b)/2
}

ave 是纯函数吗?我认为是的,因为它没有副作用,并且仅取决于类的不可变状态。但这实际上违反了 wiki 上的纯函数定义,即纯函数通常不应访问非局部变量。

关于关闭的类似问题:

def fcn(a:Int, b: Int): Unit = {
def ave = (a+b) / 2
}

对我来说,这两个 ave 都是纯函数,相当于“val”(统一访问原则)。

但是如何严格证明呢?此外,如果 a 和 b 字段是可变的,则 ave 不再是纯函数式的。

class Ave2(var a: Int, var b: Int) {
def ave = (a+b)/2 // Not pure functional
}

纯函数的另一个定义来自《Scala 中的函数编程》一书:

An expression e is referentially transparent if, for all programs p, all occurrences of e in p can be replaced by the result of evaluating e without affecting the meaning of p. A function f is pure if the expression f(x) is referentially transparent for all referentially transparent x

那么问题是,对于一个类来说,类中的可变状态是否是引用透明的(在我的示例中是 var a, var b)? (如果是的话,那么Ave2中的ave方法就变成了纯函数,这就矛盾了)

Scala 中纯函数的精确定义是什么?

最佳答案

简短回答:
只要封闭变量是不可变的,闭包就不会妨碍纯度。

长答案:
在真正的函数式编程语言中,非局部变量永远不会改变,因此闭包不会影响纯度。 Haskell 函数是纯粹的,但 Haskell 使用闭包却没有任何问题。只要您的函数遵循没有副作用的规则,并且每次调用同一组参数时都具有相同的结果(换句话说,没有可变状态),您就可以获得引用透明度,从而获得纯度。如果您对事物的理论观点挑剔,那么我完全理解对闭包的担忧,因为纯函数应该依赖于它们的参数并且仅依赖于它们的参数(但不一定是全部)。但从实践的角度来看,封闭不可变变量并不被认为是违反纯度的。

请注意,局部可变状态也不一定会危及纯度。这是一个湿滑的领域,但 Martin Odersky 有一次自己说过(如果我真的必须的话,我可以挖掘出确切的来源,它要么是 Coursera 类(class)之一的讲座,要么是《Scala 编程》一书)只要满足以下条件,变量就可以了你让他们对外界不可见。所以这个愚蠢的函数:

def addOne(i: Int) = {
var s = i
s = s + 1
s
}

可以被认为是纯粹的,即使它使用可变状态(变量s),因为可变状态不会暴露给“外部世界”,并且不会放置方法的引用透明度addOne 处于危险之中。

关于scala - Scala 中类方法和闭包上下文中的纯函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36314889/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com