Saya perlu untuk mengkomunikasikan suatu informasi dari mengkompilasi script ke Template Haskell. Saat ini mengkompilasi script menjaga informasi dalam sistem lingkungan, sehingga aku hanya membacanya menggunakan Sistem.Lingkungan.getEnvironment
dibungkus runIO
. Apakah ada cara yang lebih baik, seperti melewati beberapa argumen untuk ghc
(mirip dengan -D...
untuk C pre-processor), atau mungkin sesuatu yang khusus dirancang untuk tujuan ini di TH?
Karena begitu banyak orang yang tertarik pada pertanyaan, saya'll menambahkan pendekatan saat ini, mungkin seseorang akan menemukan itu berguna. Mungkin cara terbaik adalah jika TH diizinkan untuk membaca -D
parameter pada GHC's command line, tapi tampaknya tidak ada yang seperti ini dilaksanakan saat ini.
Modul sederhana ini memungkinkan TH untuk membaca waktu kompilasi lingkungan. Fungsi pembantu juga memungkinkan untuk membaca file; misalnya membaca path dari file konfigurasi dari lingkungan dan kemudian baca file.
{-# LANGUAGE TemplateHaskell #-}
module THEnv
(
-- * Compile-time configuration
lookupCompileEnv
, lookupCompileEnvExp
, getCompileEnv
, getCompileEnvExp
, fileAsString
) where
import Control.Monad
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Language.Haskell.TH
import Language.Haskell.TH.Syntax (Lift(..))
import System.Environment (getEnvironment)
-- Functions that work with compile-time configuration
-- | Looks up a compile-time environment variable.
lookupCompileEnv :: String -> Q (Maybe String)
lookupCompileEnv key = lookup key `liftM` runIO getEnvironment
-- | Looks up a compile-time environment variable. The result is a TH
-- expression of type @Maybe String@.
lookupCompileEnvExp :: String -> Q Exp
lookupCompileEnvExp = (`sigE` [t| Maybe String |]) . lift <=< lookupCompileEnv
-- We need to explicly type the result so that things like `print Nothing`
-- work.
-- | Looks up an compile-time environment variable and fail, if it's not
-- present.
getCompileEnv :: String -> Q String
getCompileEnv key =
lookupCompileEnv key >>=
maybe (fail $ "Environment variable " ++ key ++ " not defined") return
-- | Looks up an compile-time environment variable and fail, if it's not
-- present. The result is a TH expression of type @String@.
getCompileEnvExp :: String -> Q Exp
getCompileEnvExp = lift <=< getCompileEnv
-- | Loads the content of a file as a string constant expression.
-- The given path is relative to the source directory.
fileAsString :: FilePath -> Q Exp
fileAsString = do
-- addDependentFile path -- works only with template-haskell >= 2.7
stringE . T.unpack . T.strip <=< runIO . T.readFile
Hal ini dapat digunakan seperti ini:
{-# LANGUAGE TemplateHaskell #-}
import THEnv
main = print $( lookupCompileEnvExp "DEBUG" )
Maka:
runhaskell Utama.hs
cetak tidak Ada
;DEBUG="ya" runhaskell Utama.hs
cetakan Hanya "ya"
.Sepertinya apa yang anda coba lakukan di sini, option-D di ghc tampaknya untuk menentukan waktu kompilasi variabel.
Di sini, pada subjek yang sama adalah pertanyaan yang tampaknya juga menjawab bagian lain dari pertanyaan anda. Dari apa yang saya tahu, untuk melakukan kompilasi bersyarat, anda melakukan sesuatu seperti:
#ifdef MACRO_NAME
//Do stuff here
#endif