看一下这个描述traceIO,我觉得它确实hPutStrLn stderr做到了.但是,当我查看其源代码时:
traceIO :: String -> IO ()
traceIO msg = do
withCString "%s\n" $ \cfmt -> do
-- NB: debugBelch can't deal with null bytes, so filter them
-- out so we don't accidentally truncate the message. See Trac #9395
let (nulls, msg') = partition (=='\0') msg
withCString msg' $ \cmsg ->
debugBelch cfmt cmsg
when (not (null nulls)) $
withCString "WARNING: previous trace message had null bytes" $ \cmsg ->
debugBelch cfmt cmsg
Run Code Online (Sandbox Code Playgroud)
它似乎使用了一个外部例程debugBelch,我没有找到任何文档.那么traceIO做不了什么hPutStrLn stderr呢?
我能想到的一件事是,它可以确保将字符串作为一个单元打印,而内部没有任何其他跟踪消息。事实上,一项实验似乎证实了这一点:
Prelude Debug.Trace System.IO> traceIO $ "1" ++ trace "2" "3"
2
13
Prelude Debug.Trace System.IO> hPutStrLn stderr $ "1" ++ trace "2" "3"
12
3
Run Code Online (Sandbox Code Playgroud)
另一个区别是它似乎删除了不能安全打印到 stderr 的字符:
Prelude Debug.Trace System.IO> hPutStrLn stderr "\9731"
*** Exception: <stderr>: hPutChar: invalid argument (invalid character)
Prelude Debug.Trace System.IO> traceIO "\9731"
Prelude Debug.Trace System.IO>
Run Code Online (Sandbox Code Playgroud)
正如@dfeuer 提醒我的那样,这些功能中没有一个是不可能用 Haskell 编写的。所以决定因素可能是这样的:debugBelch已经是一个预定义的 C 函数,在 GHC 的运行时系统中到处使用,它是用 C 和 C 编写的——而不是 Haskell。
| 归档时间: |
|
| 查看次数: |
186 次 |
| 最近记录: |