好,这里有一个简单的问题。我写了一个函数debug :: String -> IO ()
。我想设置一些东西,当我用一种方式编译程序时,这个函数写入标准错误,如果我用另一种方式编译程序,这个函数变为无操作。是否有一些简单的编译时开关来做到这一点?或者我必须自己实现一些东西?
我不认为让trace
参与是解决这个问题的正确方法。
相反,您可以使用预处理器来禁用/启用调试消息。将以下内容放到另一个文件中:
{-# LANGUAGE CPP #-}
import System.IO
debug :: String -> IO ()
debug message =
#ifdef DEBUG
hPutStrLn stderr message
#else
return ()
#endif
{-# LANGUAGE CPP #-}
行为当前文件启用C预处理器。然后,您可以使用ghc -DDEBUG
或仅使用ghc
编译带有/而不调试的文件。
您可以使用CPP预处理器和#ifdef
来完成此操作。
-
首先,使用
#ifdef
在两个版本的功能之间进行选择。{-# LANGUAGE CPP #-} module Logging (debug) where debug :: String -> IO () #ifdef DEBUG debug = putStrLn #else debug _ = return () #endif
-
然后,在
.cabal
文件中添加一个标志来控制它。... flag debug description: Enable debug logging default: False executable foo -- or library if flag(debug) cpp-options: -DDEBUG ...
-
最后,要启用调试,在配置时使用
-f
启用标志:$ cabal configure -f debug
为了补充这里给出的优秀答案,我想提到这种方法,以防人们(像我一样)同时使用stack
和hpack
的最新版本。
在package.yaml
文件中,我添加了以下内容:
flags:
debug: # Or whatever name you want to give to the flag
description: Enable debug
manual: True
default: False
when:
- condition: flag(debug)
cpp-options: -DDEBUG
然后我建议将Debug.Trace
中的traceIO
与NoTrace
结合使用,以便在没有debug
标志的情况下编译代码时traceIO
将不起作用:
{-# LANGUAGE CPP #-}
-- ...
#ifdef DEBUG
import Debug.Trace
#else
import Debug.NoTrace
#endif
-- ...
someFunc :: IO ()
someFunc = do
-- ...
traceIO "Whatever..."
当使用stack时,debug
标志可以通过使用--flag
选项来启用:
stack build --flag "your-package:debug"
或者如果你正在测试你的包:
stack build --flag "your-package:debug"
如果没有使用hpack
,那么您可以按照下面的说明配置您的cabal文件hammar。