【问题标题】:Conditional compilation in Haskell other than using CPPHaskell 中的条件编译,而不是使用 CPP
【发布时间】:2022-01-15 18:42:12
【问题描述】:

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

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

当然,它工作得很好,但它相当笨拙且不惯用。难道真的没有其他机制可以实现条件编译吗?

(我真正想使用它的具体情况是Text.Megaparsec.Debug.dbg 函数。它产生的解析线索非常有用,但是源代码中到处都是#ifdef...#endif 噪音,这使得这一切都相当不可读。顶部的包装函数会消除大部分噪音,但我还是想知道。)

【问题讨论】:

  • 我想说CPP是实现条件编译的常用方式。我还要说,目前,CPP 是惯用的方式。另一种选择是 Template Haskell,在某些情况下,它可以用于该目的,但我从未见过它被这样使用。
  • 另一个可能的选择是使用背包。将调试函数放在模块签名中,然后编写两个带有实现的内部库:一个是无操作的,另一个是委托真正的调试函数。

标签: haskell c-preprocessor conditional-compilation


【解决方案1】:

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

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

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


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

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

在包配置中,添加一个标志以在debug/nodebug/ 之间进行选择。

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

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

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

【讨论】:

    猜你喜欢
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 2017-04-28
    • 1970-01-01
    相关资源
    最近更新 更多