18

我以为已经有一个关于这个的问题,但我找不到。

我希望我的程序打印出它的编译日期。设置它的最简单方法是什么?

我能想到几种可能性,但没有一种是你所说的“简单”。理想情况下,我希望能够在每次运行时打印出编译日期ghc --make FooFoo

浮现在脑海中的各种不容易的可能性:

  • 学习模板 Haskell。弄清楚如何使用Data.Time来获取今天的日期。找到一种方法如何将其转换为字符串。(现在我的程序需要 TH 才能工作。我还需要说服它每次都重新编译那个模块,否则我会得到那个模块的编译日期[它永远不会改变],而不是整个程序。)

  • 编写一个 shell 脚本,生成一个包含系统日期的小 Haskell 模块。(现在我必须使用那个 shell 脚本而不是直接编译我的程序。此外,Windows 上的 shell 脚本还有很多不足之处!)

  • 坐下来写一些 Haskell 代码,它会生成一个包含日期的小 Haskell 模块。(比以前的想法更便携 - 但仍需要额外的构建步骤,否则打印的日期将不正确。)

  • 通过 Cabal 可能有一些方法可以做到这一点 - 但我真的想打包这个小程序只是为了获得一个约会设施吗?

有人有更简单的建议吗?

4

2 回答 2

28

为此使用 Template Haskell 相对简单。你只需要:

  1. 在 Template Haskell monad 中运行 IO 操作:

    runIO :: IO a -> Exp a
    
  2. 然后创建一个字符串文字:

    stringE :: String -> ExpQ
    
  3. 将整个表达式放在准引号内。

    $( ... )
    

该程序将打印其编译时间:

{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import Data.Time

main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime))

您可以将相关片段放入导入所有其他模块的模块中,以确保重新编译它。

或者从您的版本控制系统中获取当前的修订信息。请参阅:TemplateHaskell 和 IO

于 2013-07-22T21:34:30.243 回答
10

预处理器有助于定义__DATE____TIME__宏(就像在 C 中一样),所以这有效:

{-# LANGUAGE CPP #-}
main = putStrLn (__DATE__ ++ " " ++ __TIME__)

这可能比 Michal 对 Template Haskell 的建议更简单,但不允许您选择日期的格式。

于 2013-07-27T23:27:07.757 回答