Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Debugging 如何在Haskell中打印行号和堆栈跟踪?_Debugging_Haskell - Fatal编程技术网

Debugging 如何在Haskell中打印行号和堆栈跟踪?

Debugging 如何在Haskell中打印行号和堆栈跟踪?,debugging,haskell,Debugging,Haskell,我把它附加到我的print语句中,它们有一个堆栈跟踪 Haskell是如何做到这一点的?一个选项似乎是使用库,例如,您可以在其中使用行信息编写错误消息: {-# LANGUAGE TemplateHaskell #-} -- app/Main.hs module Main where import Debug.Trace.LocationTH main :: IO () main = do $failure "Error" putStrLn "Hello" 给我 my-e

我把它附加到我的print语句中,它们有一个堆栈跟踪


Haskell是如何做到这一点的?

一个选项似乎是使用库,例如,您可以在其中使用行信息编写错误消息:

{-# LANGUAGE TemplateHaskell #-}
-- app/Main.hs
module Main where

import Debug.Trace.LocationTH

main :: IO ()
main = do
    $failure "Error"
    putStrLn "Hello"
给我

my-exe:app/Main.hs:10:5-12:Error

它还提供了一个可以查看的字符串,以确定行号。然而,我想这是有点不赞成的,这取决于您的用例。例如,我不希望看到这种方法仅用于记录行号

还有更多关于Haskell调试技术的内容


老实说,也许这不是个好主意。您打算如何处理线路号?

我想我找到了一个解决方案:

Trace:用于跟踪和监视执行的函数

traceStack::String->a->a源

与跟踪类似,但如果有可用的调用堆栈,则另外打印一个调用堆栈

在当前GHC实现中,调用堆栈仅在以下情况下可用 该程序是用-prof编写的;否则,traceStack将正常工作 跟trace一模一样。调用堆栈中的条目对应于SCC 注释,因此使用-fprof auto或 -fprof auto调用自动添加SCC注释

自:4.5.0.0


^

如@user2407038中所述,现代GHC提供了调用堆栈,请参见

按如下方式打印调用堆栈:

import           GHC.Stack

msgStacktraced :: HasCallStack => String -> IO ()
msgStacktraced msg = putStrLn (msg ++ "\n" ++ prettyCallStack callStack)

您还需要对任何可以调用
msgstacktracked
的对象设置
HasCallStack
约束,否则它将从调用堆栈中隐藏。

我喜欢的调试方式是将这些约束散布在代码的关键区域(即与操作相对应的控制器)我让它们打印出来,这样堆栈轨迹就可以点击了。这些可点击的堆栈跟踪留下了一条可以向前或向后浏览的轨迹,允许我将代码区域映射到功能,而无需担心意外跳过断点。我明白了。我想在某种意义上,这是一种相当有趣的调试方式。也许有一个可插拔的东西可以用于某些应用程序(我猜是网站?)会很好。在任何情况下,在这种情况下,我认为这可能不是最好的方式。您可能想考虑一些Haskell模板来获取行号。看看这个答案:如果你能把它变成一个很好的工具来帮助调试,那会很有趣。我不确定这一切在函数内联等情况下有多健壮。我实际上已经把它变成了一个非常可爱的工具,具有日志记录级别,并且能够在设置调试标志(-)时禁用标记的打印。我更喜欢它,而不是一行一行地在一个方向上遍历大型代码库。IDE需要的不仅仅是行号——它需要堆栈跟踪的完整行(与java堆栈跟踪相同),这样当您单击它时,您就可以转到该行。这种基于haskell模板的方法基本上已经被淘汰了。@unhammer它适用于GHC网站上仍然可用的GHC的每个版本,可以追溯到9(!)年。是我能找到的描述它的文档的最旧版本(当然,阅读现代版本——这个链接只是为了好奇)。您需要启用扩展名,
-XImplicitParams
,但您可以直接使用
CallStack
,而不使用它。如果您觉得有必要回答,请随意写下您选择的答案:)
import           GHC.Stack

msgStacktraced :: HasCallStack => String -> IO ()
msgStacktraced msg = putStrLn (msg ++ "\n" ++ prettyCallStack callStack)