런타임에 TemplateHaskell 생성 코드를 생성하고 실행할 수 있습니까?런타임에 생성 된 TemplateHaskell 코드를 생성하고 실행할 수 있습니까?
나는, 실행시에, C를 사용하여 다음을 수행 할 수 있습니다
- 함수의 소스 코드를 작성, GCC에
- 콜 아웃이 .so를 (리눅스) (또는 사용 LLVM 등으로 컴파일 .),
- .so를로드하고
- 함수를 호출하십시오.
Template Haskell과 비슷한 점이 있습니까?
런타임에 TemplateHaskell 생성 코드를 생성하고 실행할 수 있습니까?런타임에 생성 된 TemplateHaskell 코드를 생성하고 실행할 수 있습니까?
나는, 실행시에, C를 사용하여 다음을 수행 할 수 있습니다
Template Haskell과 비슷한 점이 있습니까?
예, 가능합니다. GHC API는 Template Haskell을 컴파일합니다. 개념 증명은 https://github.com/JohnLato/meta-th에서 가능합니다. 매우 정교하지는 않지만 형식 안전성을 제공하는 하나의 일반 기술을 보여줍니다. 템플릿 하스켈 표현식은 Meta
유형을 사용하여 빌드되며, 컴파일되고 사용 가능한 함수로로드 될 수 있습니다.
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wall #-}
module Data.Meta.Meta (
-- * Meta type
Meta (..)
-- * Functions
, metaCompile
) where
import Language.Haskell.TH
import Data.Typeable as Typ
import Control.Exception (bracket)
import System.Plugins -- from plugins
import System.IO
import System.Directory
newtype Meta a = Meta { unMeta :: ExpQ }
-- | Super-dodgy for the moment, the Meta type should register the
-- imports it needs.
metaCompile :: forall a. Typeable a => Meta a -> IO (Either String a)
metaCompile (Meta expr) = do
expr' <- runQ expr
-- pretty-print the TH expression as source code to be compiled at
-- run-time
let interpStr = pprint expr'
typeTypeRep = Typ.typeOf (undefined :: a)
let opener = do
(tfile, h) <- openTempFile "." "fooTmpFile.hs"
hPutStr h (unlines
[ "module TempMod where"
, "import Prelude"
, "import Language.Haskell.TH"
, "import GHC.Num"
, "import GHC.Base"
, ""
, "myFunc :: " ++ show typeTypeRep
, "myFunc = " ++ interpStr])
hFlush h
hClose h
return tfile
bracket opener removeFile $ \tfile -> do
res <- make tfile ["-O2", "-ddump-simpl"]
let ofile = case res of
MakeSuccess _ fp -> fp
MakeFailure errs -> error $ show errs
print $ "loading from: " ++ show ofile
r2 <- load (ofile) [] [] "myFunc"
print "loaded"
case r2 of
LoadFailure er -> return (Left (show er))
LoadSuccess _ (fn :: a) -> return $ Right fn
이 함수는 ExpQ
소요되며, 먼저 일반 Exp
를 만들 IO에서 실행됩니다. Exp
은 런타임에 컴파일되고로드되는 소스 코드에 꽤 인쇄됩니다. 실제로, 나는보다 어려운 장애물 중 하나가 생성 된 TH 코드에서 올바른 수입을 지정하는 것을 발견했습니다.
그건 약간 무서운 데요. –
템플릿 haskell 생성 된 코드는 런타임에 실행됩니다 : P – Satvik
@Satvik - 분명히 생성 된 코드의 런타임에 있지만 생성기의 * 런타임에서 생성 된 코드를 실행하는 데 특별히 신경을 썼습니다. – fadedbee