【问题标题】:How to print with line number and stack trace in Haskell? [duplicate]如何在 Haskell 中打印行号和堆栈跟踪? [复制]
【发布时间】:2016-02-08 01:43:51
【问题描述】:

我在 Java 中将此附加到我的打印语句中,并且它们有一个堆栈跟踪...

How can we print line numbers to the log in java

public static int getLineNumber() {
    // The second row of the stack trace had the caller file name, etc.
    return Thread.currentThread().getStackTrace()[2];
}

Haskell 我该怎么做?

【问题讨论】:

    标签: debugging haskell


    【解决方案1】:

    一个选项似乎是使用像loc-th 这样的库,例如,您可以在其中编写带有行信息的错误消息:

    {-# 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 调试技术的更多信息here

    不过,老实说,也许这不是最好的主意。你打算用行号做什么?

    【讨论】:

    • 我喜欢进行调试的方式是我将它们洒在代码的关键区域(即对应于操作的控制器),并以这样的方式打印出来,即堆栈跟踪是点击 -有能力的。这些可点击的堆栈跟踪留下了我可以前进或后退的痕迹,让我可以将代码区域映射到功能,而不必担心意外跳过断点。
    • 我明白了。我想从某种意义上说,这是一种相当有趣的调试方式。也许有一个可以在某些应用程序上使用的可插拔的东西会很好(我猜是网站?)无论如何,在那种情况下,我认为这可能不是最好的方法。您可能需要考虑一些模板 haskell 来获取行号。看到这个答案:stackoverflow.com/a/13407182/154152 看看你能不能把它变成一个很好的工具来帮助调试会很有趣。我不确定这一切在函数内联等情况下有多健壮。
    • 我实际上已经把它变成了一个非常可爱的工具,具有日志记录级别和在设置调试标志时禁用标记打印的能力 (github.com/JohnReedLOL/JohnsUtils - github.com/JohnReedLOL/JohnsUtils/blob/master/src/info/…)。我喜欢它比在一个方向上逐行浏览大型代码库要好得多。 IDE 需要的不仅仅是一个行号 - 它需要来自堆栈跟踪的完整行(与 java 堆栈跟踪相同),以便在单击它时转到该行。
    • 这种基于模板-haskell 的方法基本上已被modern ghc features 淘汰。
    • @unhammer 它适用于 GHC 网站上仍然可用的每个 GHC 版本,可以追溯到 9 (!) 年。 Here 是我能找到的描述它的文档的最旧版本(当然,请阅读现代版本——该链接仅供好奇)。您需要启用扩展程序-XImplicitParams,但您可以在没有它的情况下直接使用CallStack。如果您认为值得回答,请随意写下您选择的答案:)
    【解决方案2】:

    我想我找到了解决办法:

    Debug.Trace:用于跟踪和监控执行的函数。

    traceStack :: String -> a -> 源代码

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

    在当前的 GHC 实现中,调用堆栈仅在以下情况下可用 该程序是用 -prof 编译的;否则 traceStack 的行为 就像跟踪一样。调用栈中的条目对应SCC 注释,因此最好使用 -fprof-auto 或 -fprof-auto-calls 自动添加 SCC 注释。

    自:4.5.0.0

    ^https://hackage.haskell.org/package/base-4.8.2.0/docs/Debug-Trace.html

    【讨论】:

      【解决方案3】:

      正如 @user2407038 的 comment 中所述,现代 GHC 提供了 CallStack,请参阅 https://www.stackage.org/haddock/lts-17.13/base-4.14.1.0/GHC-Stack.html#t:HasCallStack 上的文档

      像这样打印调用堆栈:

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

      对于任何可以调用 msgStacktraced 的东西,您都需要使用 HasCallStack 约束,否则它将从调用堆栈中隐藏。

      【讨论】:

        猜你喜欢
        • 2015-07-27
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        • 1970-01-01
        • 2015-06-07
        • 2012-01-03
        • 2017-08-31
        • 2020-07-25
        相关资源
        最近更新 更多