haskell - 如何为名称中包含非字母字符的库定义 MIN_VERSION_𝑙𝑖𝑏 宏?

标签 haskell c-preprocessor versioning ghc cabal

cabal ,或 more recently GHC itself , 预定义允许检查使用哪个库的版本的 CPP 宏。它在简单的例子中很容易工作,比如

#if MIN_VERSION_base(4,0,0)
... code that works with base-4 ...
#else
... code that works with base-3 ...
#endif

但是,CPP 宏名称比 Cabal 包名称更受限制,因此以下内容不起作用:
#if !MIN_VERSION_quickcheck-instances(0,3,17)
instance Arbitrary SBS.ShortByteString where arbitrary = fmap SBS.pack arbitrary
#endif

错误:在标记“(”之前缺少二元运算符
#if !MIN_VERSION_quickcheck-instances(0,3,17)
^
|
18 | #if !MIN_VERSION_quickcheck-instances(0,3,17)
| ^
“gcc”在“C 预处理器”阶段失败。 (退出代码:1)

似乎没有正确记录如何处理这样的库名称。

最佳答案

简答 : 连字符 ( - ) 被替换为下划线 ( _ )。

据我所知,宏是在 generatePackageVersionMacros function of the DriverPipeline.hs file 中生成的。 :

generatePackageVersionMacros :: [PackageConfig] -> String
generatePackageVersionMacros pkgs = concat
  -- Do not add any C-style comments. See Trac #3389.
  [ generateMacros "" pkgname version
  | pkg <- pkgs
  , let version = packageVersion pkg
        pkgname = map fixchar (packageNameString pkg)
  ]

fixchar :: Char -> Char
fixchar '-' = '_'
fixchar c = c

generateMacros :: String -> String -> Version -> String
generateMacros prefix name version =
  concat
  ["#define ", prefix, "VERSION_",name," ",show (showVersion version),"\n"
  ,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n"
  ,"  (major1) <  ",major1," || \\\n"
  ,"  (major1) == ",major1," && (major2) <  ",major2," || \\\n"
  ,"  (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")"
  ,"\n\n"
  ]
  where
(major1:major2:minor:_) = map show (versionBranch version ++ repeat 0)


如您所见 packageNameString通过执行 map fixchar在上面。连字符 ( - ) 替换为下划线 ( _ )。因此,宏可以写成:
#if !MIN_VERSION_quickcheck_instances(0,3,17)
instance Arbitrary SBS.ShortByteString where arbitrary = fmap SBS.pack arbitrary
#endif

关于haskell - 如何为名称中包含非字母字符的库定义 MIN_VERSION_𝑙𝑖𝑏 宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50039809/

相关文章:

haskell - 带有两个参数的绑定(bind)运算符 (=<<)

git - 通过复制旧的 git 存储库来创建新的 git 存储库

osgi - OSGi 包中的版本更改

c - 为什么我的讲师写的所有 C 文件的第一行都以一个 # 开头?

xml - 对 XML 模式进行版本控制的最佳实践是什么?

haskell - 在nix上的haskell开发环境中使用hoogle

haskell - 类型系列无法返回 RankN 类型——解决方法还是替代方案?

haskell - 很难定义所有值的单子(monad)

windows - 了解 MAKEINTRESOURCEW 定义

使用字符串检查宏定义