haskell - Haskell 中按名称调用与按值调用

标签 haskell

如果按值调用和按名称调用都有效,那么它们是否会提供相同的结果? 例如:

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/

相关文章:

haskell - 为什么 "map (filter fst)"的类型是 "[[(Bool, a)]] -> [[(Bool, a)]]"?

windows - 如何在 ghci 中使用数学符号(函数名)?

debugging - 如何在 Haskell 中编写 showIt 函数?

haskell - 在do block 中具有不同Left的Chain ExceptT

haskell - 让模板haskell用源信息(例如行号)包装函数的正确方法是什么

haskell - 多参数一元绑定(bind)

haskell - GHC 任何结果都会导致 "ld: library not found for -lgmp"

haskell - 一种有趣的模式

haskell - 过滤应用程序

emacs - 运行 hasktags 获取大量 .hs 源文件以获取 CTAGS 文件(普通 Windows)