GHC: введите дату компиляции

Я думал, что уже будет вопрос об этом, но я не могу его найти.

Я хочу, чтобы моя программа распечатывала дату, когда она была скомпилирована. Какой самый простой способ установить это?

Я могу думать о нескольких возможностях, но ни один из них не является тем, что вы бы назвали "легким". В идеале я хотел бы просто сделать ghc --make Foo и Foo распечатать дату компиляции каждый раз, когда я запустил его.

Различные непростые возможности, которые spring:

  • Изучите шаблон Haskell. Выясните, как использовать Data.Time для получения сегодняшней даты. Найдите способ преобразования этого в строку. (Теперь моя программа требует TH для работы. Мне также нужно убедить ее перекомпилировать этот модуль каждый раз, иначе я получаю дату компиляции для этого модуля [который никогда не изменяется], а не всей программы.)

  • Напишите оболочку script, которая генерирует крошечный модуль Haskell, содержащий системную дату. (Теперь мне нужно использовать эту оболочку script, а не компилировать мою программу напрямую. Кроме того, shell-скрипты на Windows оставляют желать лучшего!)

  • Сядьте и напишите некоторый код Haskell, который генерирует крошечный модуль Haskell, содержащий дату. (Более портативный, чем предыдущая идея, но все еще требует дополнительных шагов сборки или напечатанной даты будет некорректной.)

  • Возможно, есть какой-то способ сделать это через Cabal - но действительно ли я хочу упаковать эту небольшую программу только для того, чтобы получить дату?

Есть ли у кого-нибудь более простые предложения?

Ответы

Ответ 1

Использование шаблона Haskell для этого относительно просто. Вам просто нужно:

  • Запустите IO-действие в монаде Haskell:

    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))

Вы можете поместить соответствующий фрагмент в модуль, который импортирует все другие модули, чтобы убедиться, что он перекомпилирован.

Или получить текущую информацию о пересмотре в вашей системе управления версиями. Смотрите: TemplateHaskell и IO

Ответ 2

Препроцессор успешно определяет макросы __DATE__ и __TIME__ (как и в C), поэтому это работает:

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

Это, вероятно, проще, чем предложение Michal Template Haskell, но не позволяет вам выбрать формат даты.