gpt4 book ai didi

haskell - 两次函数调用但只显示一条跟踪

转载 作者:行者123 更新时间:2023-12-02 12:10:51 27 4
gpt4 key购买 nike

使用 GHC 8.0.2 版以下程序:

import Debug.Trace

f=trace("f was called")$(+1)

main = do
print $ f 1
print $ f 2

输出:

f was called
2
3

这是预期的行为吗?如果是,为什么?我预计字符串 f was called 会打印两次,一次在 2 之前,一次在 3 之前。

TIO 上的结果相同:Try it online!

编辑但是这个程序:

import Debug.Trace

f n=trace("f was called:"++show n)$n+1

main = do
print $ f 1
print $ f 2

输出:

f was called:1
2
f was called:2
3

Try it online!

我怀疑这些行为与懒惰有关,但我的问题仍然存在:这是预期的行为吗?如果是,为什么?

Hackage 断言:

The trace function outputs the trace message given as its first argument, before returning the second argument as its result.

我在第一个示例中没有看到它。

编辑 2 基于 @amalloy 评论的第三个示例:

import Debug.Trace

f n=trace "f was called"$n+1

main = do
print $ f 1
print $ f 2

输出:

f was called
2
f was called
3

最佳答案

您的跟踪在定义 f 时打印,而不是在调用它时打印。如果您希望跟踪作为调用的一部分发生,则应确保在收到参数之前不会对其进行评估:

f x = trace "f was called" $ x + 1

另外,当我运行你的 TIO 时,我根本没有看到跟踪出现。 trace 并不是一种真正可靠的打印方式,因为它欺骗了语言所基于的 IO 模型。评估顺序中最细微的变化都会扰乱它。当然,您可以使用它进行调试,但即使是这个简单的示例也无法保证它有多大帮助。

在您的编辑中,您引用了 trace 的文档:

The trace function outputs the trace message given as its first argument, before returning the second argument as its result.

事实上,这正是您的程序中发生的情况!定义f时,

trace "f was called" $ (+ 1)

需要评估。首先,打印“f was called”。然后,trace 计算并返回 (+ 1)。这是 trace 表达式的最终值,因此 (+ 1) 就是 f 的定义。 痕迹消失了,看到了吗?

关于haskell - 两次函数调用但只显示一条跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45967186/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com