2013-07-22 23 views
16

Bunun hakkında zaten bir soru olacağını düşündüm, ama bulamıyorum.GHC: derleme tarihini ekle

Programımın derlendiği tarihi yazdırmasını istiyorum. Bunu ayarlamanın en kolay yolu nedir?

Birkaç olasılık düşünebilirim, ancak bunların hiçbiri "kolay" diyeceğiniz şey değil. İdeal olarak, her çalıştırdığımda ghc --make Foo yapabilmek ve Foo derleme çıktısını almak istiyorum. akla

Çeşitli olmayan kolay olasılıklar:

  • Şablon Haskell öğrenin. Bugünün tarihini almak için Data.Time'u nasıl kullanacağınızı öğrenin. Bunu bir dizeye dönüştürmenin yolunu bulun. (Şimdi programım çalışmak için TH gerektirir. Ayrıca, her zaman bu modülü yeniden derlemek için ikna etmem gerekiyor, aksi takdirde tüm modül yerine [asla değişmez] bu modül için derleme tarihini aldım.)

  • Sistem tarihini içeren küçük bir Haskell modülü oluşturan bir kabuk komut dosyası yazın. (Şimdi! Ayrıca Windows üzerinde kabuk komut dosyası çok istenen bırakır. O shell script kullanmak yerine doğrudan programımı derlemek zorunda)

  • Sit aşağı ve dolu küçücük Haskell modülünü oluşturur bazı Haskell kod yazmak tarih. (Önceki fikirden daha taşınabilir - ancak yine de fazladan oluşturma adımları gerektirir veya yazdırılan tarih yanlış olur.)

  • Cabal üzerinden bunu yapmanın bir yolu olabilir - ancak bu küçük programı gerçekten paketlemek istiyorum bir tarih tesisi almak için?

herkes herhangi basit bir öneriniz var mı?

+1

Alias ​​ghc Tarih dizgisi için # -} 've' şimdi = ŞİMDİ '. Çirkin hack, sizi daha fazla iş alan daha temiz bir alternatife itecek kadar çirkin olabilir. –

+0

@DanielFischer Görünüşe göre, Windows kabuğu bir komutun çıktısından bir değişken belirleme yeteneğinden yoksundur. Bunun yerine, stdin metnini okuyan SET/P VAR = 'içeren bir kesmek kullanmalısınız. Komut çıktısını bir dosyaya aktarırsanız, daha sonra tekrar boruya gönderirseniz, istediğiniz efekti elde edebilirsiniz ... ancak JESUS! > _ < – MathematicalOrchid

+0

Oh, vay. PowerShell bile bu yeteneğe sahip değil mi? –

cevap

26

Şablon Haskell'in kullanılması bunun için oldukça basittir. Sadece gerekir:

    Şablon Haskell monad içinde
  1. çalıştırın IO eylemi:

    stringE :: String -> ExpQ 
    
  2. bir dahilinde bir bütün ifadeyi koyun:

    runIO :: IO a -> Exp a 
    
  3. Sonra ile değişmez bir dize oluşturmak quasiquote. Bunu derlenmiş çekirdekler emin olmak için tüm diğer modülleri ithal eden bir modüle ilgili parçasını koyabilir

    {-# LANGUAGE TemplateHaskell #-} 
    import Language.Haskell.TH 
    import Data.Time 
    
    main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime)) 
    

    :

    $(...) 
    

Bu program kendi derleme zamanı yazdırır. Veya sürüm revizyon bilgilerinizi sürüm sisteminizden alınız.TemplateHaskell and IO

+1

Ne harika bir ilk cevap! Yığın Taşması'na Hoş Geldiniz! – AndrewC

+0

Bu, en temiz çözüm hakkında görünüyor. Sürüm dizesi birkaç farklı yerde kullanılır, bu yüzden bu kodu ayrı bir modülde koyardım. Öngördüğüm tek sorun, her defasında yeniden derlenen sürüm modülünü almak; belki her zaman kaynak dosyaya "dokunmak" için TH kullanabilir miydim? – MathematicalOrchid

+0

MathematicalOrchid: Bu yüzden bu modülün diğer tüm üst düzey modülleri ithal etmesini önerdim. Ya da bu kodu 'ana' modülüne koyabiliriz. Sonra her zaman yeniden derlenir. Diğer çözümde aynı sorun var ve kaynak dosyaya “dokunmaya” çalışmak, bazıları için daha kirli bir çözüm gibi görünebilir. –

7

önişlemci yardımsever (sadece C gibi) __DATE__ ve __TIME__ makro tanımlar, bu nedenle bu işleri: Bkz

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

Bu Şablon Haskell Michal'ın öneri daha muhtemelen daha basittir, ancak size izin vermez Tarihin formatını seçin. # DİL CPP - `` için ghc -DNOW = "\" `date` \ ""` `(yani Windows kabuk için nasıl görüneceğini hiçbir fikri), ve modül kullanımda` {eşdeğer bir şeye

+0

elbette, programda tarihi bir kez aldığınız zaman, istediğiniz gibi yönlendirebilirsiniz. – muhmuhten

+0

Bu durumun böyle olabileceğini umuyordum - ancak belgede bundan bahsetmemiştim. Ayrıca, "__DATE __" 'yazmanın değil," __DATE__ "ın yazılmasının bir nedeni var mı? – MathematicalOrchid

+0

GHC, yalnızca C önişlemcisini çağırır, böylece orada belgelenen önceden tanımlanmış makroları bulabilirsiniz. Yararlı olanlardır '__DATE__',' __TIME__', '__FILE__' (kaynak dosya adı) ve' __LINE__' (kaynak dosya satırı numarası) - son ikisi, kaynak konumunu içeren bir hata makrosu tanımlamak için kullanışlıdır. Neden "__DATE __" 'çalışmazsa, önişlemci bir dizenin içindeki makroları genişletmez. Ayrıca, __DATE__' kendi başına zaten bir dizgi haline gelir. –