Có, có thể. API GHC sẽ biên dịch mẫu Haskell. Một chứng minh-khái niệm có sẵn tại https://github.com/JohnLato/meta-th, trong đó, mặc dù không phải là rất phức tạp, cho thấy một kỹ thuật chung mà thậm chí cung cấp một modicum của loại an toàn. Các biểu thức Haskell mẫu được xây dựng bằng cách sử dụng loại Meta
, sau đó có thể được biên dịch và tải vào một hàm có thể sử dụng.
{-# 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
chức năng này có một ExpQ
, và lần đầu tiên chạy nó trong IO để tạo ra một đồng bằng Exp
. Sau đó, Exp
được in khá tốt vào mã nguồn, được biên dịch và tải vào thời gian chạy. Trong thực tế, tôi đã thấy rằng một trong những trở ngại khó khăn hơn là xác định chính xác nhập khẩu trong mã TH được tạo ra.
Nguồn
2013-01-22 13:49:47
Mã tạo mẫu được chạy lúc chạy: P – Satvik
@Satvik - rõ ràng là thời gian chạy của mã được tạo, nhưng tôi đặc biệt xen kẽ trong việc chạy mã được tạo tại thời gian * của máy phát * – fadedbee