Haskell 中的条件编译,而不是使用 CPP

Conditional compilation in Haskell other than using CPP

CPP 扩展允许条件编译,例如

{-# LANGUAGE CPP #-}
#ifdef DEBUG
-- some debug code
#endif

当然,它工作得很好,但它非常笨拙且不合惯用。真的没有别的机制可以实现条件编译吗?

(我真正想使用它的具体情况是 Text.Megaparsec.Debug.dbg 函数。它产生的解析轨迹非常有用,但源代码中充斥着 #ifdef... #endif 噪声使它变得相当不可读。顶部的包装函数将消除大部分噪声,但我还是想知道。)

一个轻量级的解决方案是只使用一次 CPP 来定义一个布尔值,然后可以在常规 Haskell 代码中使用:

#ifdef DEBUG
#define debug True
#else
#define debug False
#fi

如果您甚至不希望调试代码通过类型检查,也可以使用宏。


另一种不用 CPP 进行条件编译的方法是在包级别更改模块的源代码,尽管我不知道这方面的任何真实示例。

创建两个具有相同名称的模块 debug/Debug.hsnodebug/Debug.hs,两者都导出,例如,布尔值 debug :: Bool.

在包配置中,在debug/nodebug/之间添加一个标记到select。

flag debug
  description: debug mode
  default: False
  manual: True

library
  ...
  if flag(debug)
    hs-source-dirs: debug
  else
    hs-source-dirs: nodebug

现在您可以使用 -f +debug 构建库以启用调试。