gpt4 book ai didi

Haskell - 执行后打印跟踪

转载 作者:行者123 更新时间:2023-12-02 17:08:56 24 4
gpt4 key购买 nike

我有一个 Uni 项目,为一种简单的命令式语言编写一个编译器(用 Haskell 语言)。要求之一是在进入函数调用、离开函数和分配变量时打印调试语句。

输入函数时打印消息很容易,我只使用 Debug.trace,例如:

functionValue = trace "Entering function" (evaluateFunction functionArguments)

分配给变量时也适用相同的过程。我不明白的是如何在从函数调用返回时进行打印,并使输出与其他输出正确计时。到目前为止,我所做的每一次尝试都导致在“输入函数”之后立即打印“离开函数” - 我需要在打印“离开函数”之前打印函数的内部调试语句(分配和嵌套函数调用)。

我的命令式习惯告诉我,我需要一种方法在 left-function 输出之前强制执行 (evaluateFunction functionArguments),但这在 Haskell 中似乎是不可能的和错误的。

我现在得到的示例输出:

Entering main function...
Leaving main function...
Entering fn1 function...
Leaving fn1 function...
Assigning value1 to A.
Assigning value2 to C.
Entering fn2 function...
Leaving fn2 function...
Assigning value3 to B.
Assigning value4 to C.

相同程序的输出符合我需要的外观:

Entering main function...
Entering fn1 function...
Assigning value1 to A.
Leaving fn1 function...
Assigning value2 to C.
Entering fn2 function...
Assigning value3 to B.
Assigning value4 to C.
Leaving fn2 function...
Leaving main function...

那么,“run myFunctionWithTraces then print myString”的 Haskell 习惯用法是什么?

最佳答案

如果你想立即打印痕迹,你可以将函数提升到 IO monad,并将其放在两个 putStr 之间,例如

trace :: String -> IO () -> IO ()
trace name f = do
putStrLn $ "Entering " ++ name
f
putStrLn $ "Leaving " ++ name

然后:

main = trace "main" $ do
fn1
fn2

fn1 = trace "fn1" $ do
return ()

fn2 = trace "fn2" $ do
return ()

这也可以纯粹通过Writer来完成。 monad(即不打印,而只是累积调试输出)。 trace 看起来会更像这样:

trace :: String -> Writer String () -> Writer String ()
trace name f = do
tell $ "Entering " ++ name ++ "\n"
f
tell $ "Leaving " ++ name ++ "\n"

并附加使用 runWriterexecWriter 解开调试输出的步骤。

编辑:将trace推广到IO a并不太困难:

trace :: String -> IO a -> IO a
trace name f = do
putStrLn $ "Entering " ++ name
ret <- f
putStrLn $ "Leaving " ++ name
return ret

main = trace "main" $ do
a <- fn1
b <- fn2
print $ a + b

fn1 = trace "fn1" $ do
return 42

fn2 = trace "fn2" $ do
return 69

关于Haskell - 执行后打印跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10160436/

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