Programing

컴파일 타임 정보를 Template Haskell 함수에 올바르게 전달하는 방법은 무엇입니까?

lottogame 2020. 11. 6. 07:48
반응형

컴파일 타임 정보를 Template Haskell 함수에 올바르게 전달하는 방법은 무엇입니까?


컴파일 스크립트의 정보를 Template Haskell로 전달해야합니다. 난 그냥 그것을 사용하여 읽을 수 있도록 현재 컴파일 스크립트는 시스템 환경에서 정보를 보관 System.Environment.getEnvironment에 싸여 runIO. ghc( -D...C 전처리 기와 유사한) 인수를 전달하는 것과 같은 더 나은 방법 이 있습니까? 아니면 TH에서이 목적을 위해 특별히 설계된 것이 있습니까?


많은 사람들이 질문에 관심이 있기 때문에 현재 접근 방식을 추가 할 것입니다. 아마도 누군가가 유용하다고 생각할 것입니다. 아마도 가장 좋은 방법은 TH -D가 GHC의 명령 줄에서 매개 변수 를 읽을 수 있도록 허용 하는 것입니다.하지만 현재 구현 된 것과 같은 것은 없습니다.

간단한 모듈을 통해 TH는 컴파일 시간 환경을 읽을 수 있습니다. 도우미 기능을 사용하면 파일을 읽을 수도 있습니다. 예를 들어 환경에서 구성 파일의 경로를 읽은 다음 파일을 읽습니다.

{-# 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

다음과 같이 사용할 수 있습니다.

{-# LANGUAGE TemplateHaskell #-}
import THEnv
main = print $( lookupCompileEnvExp "DEBUG" )

그때:

  • runhaskell Main.hs인쇄 Nothing;
  • DEBUG="yes" runhaskell Main.hs인쇄합니다 Just "yes".

여기 에서 하려는 것처럼 보입니다. ghc의 -D 옵션은 컴파일 시간 변수를 정의하는 것 같습니다.

여기, 같은 주제에 대해 질문 의 다른 부분에도 대답하는 것처럼 보이는 질문이 있습니다. 내가 알 수 있듯이 조건부 컴파일을 수행하려면 다음과 같이하십시오.

    #ifdef MACRO_NAME
    //Do stuff here
    #endif

참고 URL : https://stackoverflow.com/questions/19679024/how-to-properly-communicate-compile-time-information-to-template-haskell-functio

반응형