Haskell GHC:插入汇编日期

Haskell GHC:插入汇编日期,haskell,ghc,Haskell,Ghc,我以为已经有问题了,但我找不到 我想让我的程序打印出编译日期。最简单的方法是什么 我能想到几种可能性,但没有一种是你所说的“容易”。理想情况下,我希望能够执行ghc——生成Foo,并让Foo在每次运行时打印出编译日期 各种不容易想到的可能性: 学习Haskell模板。了解如何使用Data.Time获取今天的日期。找到一种将其转换为字符串的方法。(现在我的程序需要TH才能工作。我还需要说服它每次重新编译该模块,否则我得到的是该模块的编译日期[它永远不会改变],而不是整个程序。) 编写一个shel

我以为已经有问题了,但我找不到

我想让我的程序打印出编译日期。最简单的方法是什么

我能想到几种可能性,但没有一种是你所说的“容易”。理想情况下,我希望能够执行
ghc——生成Foo
,并让
Foo
在每次运行时打印出编译日期

各种不容易想到的可能性:

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

  • 编写一个shell脚本,生成一个包含系统日期的小Haskell模块。(现在我不得不使用这个shell脚本,而不是直接编译我的程序。而且,Windows上的shell脚本还有很多需要改进的地方!)

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

  • 也许有一些方法可以通过阴谋集团做到这一点,但我真的想打包这个小程序只是为了得到一个约会设施吗


有人有更简单的建议吗?

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

  • 在模板Haskell monad中运行IO操作:

    runIO :: IO a -> Exp a
    
  • 然后使用以下命令创建字符串文字:

    stringE :: String -> ExpQ
    
  • 把一个完整的表达式放在一个准表达式中

    $( ... )
    
  • 此程序将打印其编译时间:

    {-# LANGUAGE TemplateHaskell #-}
    import Language.Haskell.TH
    import Data.Time
    
    main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime))
    
    {-#语言模板haskell}
    导入语言.Haskell.TH
    导入数据。时间
    
    main=print$(stringE=预处理器有助于定义
    \uuuuuuuuuuuuu日期
    \uuuuuuuuu时间
    宏(就像在C中一样),因此它可以:

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

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

    将ghc别名为相当于
    ghc-DNOW=“\''date`\'”
    (不知道这对于Windows shell会是什么样子),并在您的模块中使用
    {-\35;语言CPP}
    now=now
    用于日期字符串。丑陋的hack可能会把您推到一个更干净、需要更多工作的替代方案中。@Danielf发现Windows shell显然没有从命令输出中设置变量的能力。相反,您必须使用包含
    set/P VAR=
    的hack,它从std读取文本在中。如果您将命令输出导入文件,然后再将其导入,您可以达到您想要的效果…但是,天啊!!>\u哦,哇。连PowerShell都没有这种功能吗?@DanielFischer PowerShell可能有,是的。但我没有安装它。编写一个小Haskell脚本来生成必要的输出似乎更容易。是的。这似乎更容易嗯。多么好的第一个答案!欢迎使用堆栈溢出!这似乎是最干净的解决方案。版本字符串在几个不同的地方使用,所以我将此代码放在一个单独的模块中。我预见的唯一问题是每次重新编译版本模块;也许我可以使用TH来“触摸”MathematicalArchid:这就是为什么我建议该模块导入所有其他顶级模块。或者可以将此代码放入
    main
    模块中。然后它总是被重新编译。另一个解决方案也有同样的问题,并尝试“触摸”对于某些人来说,源文件可能看起来更脏。当然,一旦你在程序中以文本形式获得日期,你就可以随意更改它。我希望是这样,但我在文档中找不到任何关于它的提及。还有,为什么要写
    “\uuuuuuuuu date\uuuuuuuuuuu?”
    不起作用,但
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuugggggggggggg-最后两个对于定义包含源位置的错误宏很有用。至于为什么
    “\uuuuuuu日期”
    不起作用,预处理器不会在字符串文本中展开宏。此外,
    \uuuuuu日期
    本身已经展开为字符串文本。