fad*_*bee 8 c haskell runtime ghc-api template-haskell
是否可以在运行时生成并运行TemplateHaskell生成的代码?
在运行时使用C,我可以:
与模板Haskell类似的事情是否可能?
Joh*_*n L 12
是的,这是可能的.GHC API将编译Template Haskell.可以在https://github.com/JohnLato/meta-th上获得概念验证,虽然不是很复杂,但它提供了一种通用技术,甚至提供了一些类型安全性.使用Meta类型构建模板Haskell表达式,然后可以将其编译并加载到可用函数中.
{-# 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
Run Code Online (Sandbox Code Playgroud)
此函数接受一个ExpQ,并首先在IO中运行它以创建一个普通的Exp.在Exp随后适合打印到源代码,其被编译和在运行时加载的.在实践中,我发现更难的障碍之一是在生成的TH代码中指定正确的导入.
| 归档时间: |
|
| 查看次数: |
478 次 |
| 最近记录: |