【Haskell】Haskell中的条件编译

(点击上方公众号,可快速关注)

背景

最近在用Haskell语言和haskell-gi包写一款HaskellIDE,这款软件初步支持简体中文和英文两种语言环境(中文简体语言环境展示中文简体,其他环境展示英文)。实现这种国际化的需求,有多种方法,比如,在C/C++下可以使用GNUgettext,在Haskell下也有其移植。我采用了另一种方法:通过判断当前语言环境,决定要使用的语言版本,所以实现都是可以通过纯Haskell代码实现,多了一层类型安全的保证。

由于目前在Haskell中还没有好用的方法获取语言环境(glib中提供了g_get_language_names函数实际上可以达到目的,但比较难用),所以需要调用平台相关的函数,在Windows下使用GetSystemDefaultLangID。这需要根据不同的操作系统执行的不一样的代码,即根据不同的平台编译不同部分的代码,即条件编译

Haskell中的条件编译支持

比较令人失望的是,在条件编译这块,Haskell并没有自己出彩的地方,继续沿用了C/C++那一套,即使用预处理指令判断预定义的宏达到编译不同部分代码的目的。在语法上,Haskell的预编译指令跟C/C++的完全一样,所以有了C/C++的经验可以无缝迁移到Haskell上面。

下面是一些使用上的细节点:

Q1:怎么启用Haskell程序的预处理过程

我们知道,正常的Haskell程序处理过程是没有预处理的,我们需要一种方式明确告知构造过程要调用预处理器。这是通过CPP语言扩展实现的,这需要我们在源文件的顶层添加:

{-# LANGUAGE CPP #-}

Q2:Haskell提供了哪些标准宏

GHC(8.2.2)用户手册7.11.3.1. Standard CPP macros列了一些可用的宏可以用于代码,包括GHC软件版本、操作系统、硬件架构、软件包等方面的宏,下面仅摘录两个:

os_HOST_OS=1

This define allows conditional compilation based on the Operating System, where⟨os⟩ is the name of the current Operating System (eg. linux, mingw32 for Windows, solaris, etc.).

arch_HOST_ARCH=1

This define allows conditional compilation based on the host architecture, where⟨arch⟩ is the name of the current architecture (eg. i386, x86_64, powerpc, sparc, etc.).


除了这些预定义宏,你也可以在代码里像使用C/C++一样,定义自己的宏。

Q3:怎将通过命令参数定义宏

一般的C/C++编译器都允许通过编译器选项定义宏,而GHC也提供了类似的选项:

最常用的是-D选项,这跟gcc编译器的用法完全一致,可以在编译时通过定义不同的宏控制编译过程。

示例

最后一个简单例子演示怎么使用条件编译。

{-# LANGUAGE CPP #-}


main :: IO ()
main =
#if defined linux_HOST_OS
 putStrLn "Linux"
#elif defined mingw32_HOST_OS
 putStrLn "Windows"
#else
 putStrLn "Other"
#endif

有一点需要注意的是,Windows下的宏定义mingw32_HOST_OS代表全部Windows系统,不要被其中的32迷惑,以为仅代表是32Windows系统。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值