如果按值调用和按名称调用都有效,那么它们是否会提供相同的结果? 例如:
import Debug.Trace
trace :: String -> a -> a
foo x y z = y + y + z
z = foo (trace "first" 1)
(trace "second" 2)
(trace "third" 3)
Call-By-Value: "first second third" 7
Call-By-Name: "second second third" 7
Lazy Evaluation: "second third" 7
在这种情况下我们会得到三个不同的结果,但为什么呢?
最佳答案
不,每次都得到相同的结果:7
。
其他消息(“first”等)是由于使用了调试函数Debug.Trace.trace
,该函数用于生成消息它准确地揭示了表达式的求值方式。编程执行的“如何”部分通常不被视为语义(即结果)的一部分,而是仅考虑返回“什么”。
例如,语义
let f x = x in f 10 + f 10
是20,与
相同let f x = x in 2 * f 10
但是,如果我们添加痕迹,
let f x = trace "msg" x in f 10 + f 10
打印“msg”两次,因为我们调用了该函数两次。相反,
let f x = trace "msg" x in 2 * f 10
仅打印一次“msg”。这仅表明评估方式不同,而不是结果不同。
在正常的“生产”代码中,程序员不应依赖诸如 Debug.*
模块中的调试辅助工具来生成消息。事实上,这会破坏纯函数式编程的许多良好特性,并且只能用于调试目的。
关于haskell - Haskell 中按名称调用与按值调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33021264/