如果它从外部读取一些数据而不是参数,它是纯函数吗?

时间:2015-07-13 06:45:17

标签: scala functional-programming

在“Scala中的函数式编程”一书中,它提供了一些关于副作用的例子,例如:

  • 修改变量
  • 就地修改数据结构
  • 在对象上设置字段
  • 抛出异常或因错误而暂停打印到控制台或阅读用户输入
  • 读取或写入文件
  • 在屏幕上绘图

我的问题是,读取一些来自外部的数据,而不是参数使函数不纯?

E.g。

val name = "Scala"

def upcase() = name.toUpperCase

upcase函数是否纯粹?

编辑:根据这个答案:https://stackoverflow.com/a/31377452/342235,我的“函数”实际上不是函数,它是一个方法,所以我给它一个函数版本,并问同样的问题:

val name = "Scala"

val upcase: () => String = () => name.toUpperCase

2 个答案:

答案 0 :(得分:5)

不可变数据中读取并不是不纯的;该函数每次仍会返回相同的值。如果namevar,则该函数将不纯,因为外部可能会更改name,因此对upcase()的多次调用可能会评估为不同的值。

(当然也许有可能通过反思来改变name。正确地说,我们只能谈论关于允许什么样的函数调用给定函数的概念的纯度,以及什么样的我们认为是相同的副作用)

值得注意的是,你的功能并不纯粹,因为toUpperCase并不纯粹;它取决于系统的默认语言环境,并可能在不同的系统上产生不同的结果(例如在土耳其语系统上"i".toUpperCase == "İ")。您应该始终传递明确的Locale,例如def upcase() = name.toUpperCase(Locale.ENGLISH);那么这个功能就是纯粹的。

答案 1 :(得分:-1)

有趣的是,答案是“不”,但不是你认为的原因。您的upcase 不是纯函数。然而,它是纯粹的,但它是一种方法,而不是一种功能。