我需要有类似的东西
-- Main.hs
module Main where
main :: IO ()
main = do
  <import Plugin>
  print Plugin.computation
有插件就好
-- Plugin.hs
module Plugin where
computation :: Int
computation = 4
但是,我需要将插件与主应用程序一起编译.他们需要一起部署.只有模块的导入(而不是编译)才能动态发生.
我发现动态加载已编译的Haskell模块 - GHC 7.6,它在GHC 8.0.2中运行得很好,除了它在执行应用程序时需要插件的源文件在当前工作目录中.
是否可以使用GHC API从String而不是文件加载模块?http://hackage.haskell.org/package/ghc-8.2.1/docs/GHC.html#t:Target表明这是可能的,但文档有很多漏洞,我找不到实际做到这一点的方法.如果可以实现,我可以使用file-embed将插件源文件包含到已编译的二进制文件中.例:
module Main where
-- Dynamic loading of modules
import GHC
import GHC.Paths ( libdir )
import DynFlags
import Unsafe.Coerce
import Data.Time.Clock (getCurrentTime)
import StringBuffer
pluginModuleNameStr :: String
pluginModuleNameStr = "MyPlugin"
pluginSourceStr :: String
pluginSourceStr = unlines …按照此处发布的GHC教程和此代码的更改,遵循我之前的堆栈溢出问题中的建议,我已经创建了一个程序,它能够在Test.hs中编译和运行一个带有函数print的模块来打印字符串到屏幕:
import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce
main :: IO ()
main =
    defaultErrorHandler defaultLogAction $ do
      func <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "Test.hs" Nothing
        addTarget target
        r <- load LoadAllTargets
        case r of
          Failed -> error "Compilation failed"
          Succeeded -> do
            m <- findModule (mkModuleName "Test") Nothing
            setContext [IIModule m]
            value <- compileExpr ("Test.print")
            do let value' = (unsafeCoerce value) :: String -> IO …compiler-construction haskell dynamic-compilation ghc ghc-api