阅读" Scala中的函数式编程"我对有关异常不是透明透明的部分感到有些困惑。
给出的例子是
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + y
}
catch { case e: Exception => 43 }
}
因此,书中给出的论点是y
不是引用透明的,因为如果我们将它替换为try
块中的主体,我们会得到与直接运行函数不同的结果。这对我没有任何意义,因为整个函数从一开始就是非终止的,那么说函数体内的值不是引用透明的又是什么意思呢?我心中的天真替代如下
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + ((throw new Exception("fail!")): Int)
}
catch { case e: Exception => 43 }
}
并且仍然以相同的异常失败。
此外,y
本身是一个非值(它不能直接被评估为一个值),那么谈论这些表达式的引用透明度有什么意义呢?我怀疑这里有什么样的手法,所以我的推理到底是不正确的?
答案 0 :(得分:7)
本书中提到的一点是,如果它真的是引用透明的,那么你可以完全删除y
变量并将其替换为try/catch
内部,并最终得到不同的语义
因此,要点是,在例外的情况下,异常的评估点很重要。
也许你可以争辩说这两个程序在语义上并不相同,因为评估的位置在这里真正重要。如果您制作y
lazy
,则结果不会更改。