纯函数可以更改输入参数吗?

add*_*dyi 6 functional-programming kotlin

改变输入参数值的函数仍然是纯函数吗?

我的例子(科特林):

data class Klicker(
    var id: Long = 0,
    var value: Int = 0
)

fun Klicker.increment() = this.value++

fun Klicker.decrement() = this.value--

fun Klicker.reset() {
    this.value = 0
}
Run Code Online (Sandbox Code Playgroud)

维基百科说纯函数有以下两个要求:

  1. 给定相同的参数值,该函数始终计算相同的结果值。函数结果值不能依赖于在程序执行过程中或程序的不同执行之间可能发生变化的任何隐藏信息或状态,也不能依赖于来自 I/O 设备的任何外部输入。
  2. 结果的评估不会导致任何语义上可观察的副作用或输出,例如可变对象的突变或输出到 I/O 设备。

根据我的理解,我示例中的所有函数都符合第一个要求。

我的不确定性始于第二个要求。随着输入参数的变化,我改变了一个对象(违反规则),但这个对象不在函数范围内,所以也许没有违反规则?

另外,纯函数是否总是需要返回一个全新的值?

我认为,这个函数被认为是 100% 纯的:

fun pureIncrement(klicker: Klicker): Klicker {
    return klicker.copy(value = klicker.value++)
}
Run Code Online (Sandbox Code Playgroud)

温柔点,这是我的第一个 Stackoverflow 问题。

yol*_*ole 4

increment函数decrement都不满足纯函数的要求。它们的返回值取决于类的状态Klicker,该状态可能会在程序执行过程中发生变化,因此无法满足第一个要求。结果的评估会改变可变Klicker实例,因此第二个要求也无法满足。可变数据在哪个范围内并不重要;纯函数根本不能改变任何数据。

reset函数仅违反了第二个要求。

如果将其更改为:该pureIncrement函数可以变得纯净:

fun pureIncrement(klicker: Klicker): Klicker {
    return klicker.copy(value = klicker.value + 1)
}
Run Code Online (Sandbox Code Playgroud)