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.hs
和 nodebug/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
构建库以启用调试。
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.hs
和 nodebug/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
构建库以启用调试。