问题 动态加载编译的Haskell模块 - GHC 7.6


我正在尝试使用GHC API动态编译和加载Haskell模块。我理解API从一个版本到另一个版本的波动很大,所以我特别谈到GHC 7.6。*。

我试过在MacOS和Linux上运行相同的代码。在这两种情况下,插件模块都可以正常编译,但在加载时会出现以下错误: Cannot add module Plugin to context: not interpreted

问题类似于中的问题 这个 模块只有在主机程序的同一运行中编译时才会加载的地方。

-- Host.hs: compile with ghc-7.6.*
-- $ ghc -package ghc -package ghc-paths Host.hs
-- Needs Plugin.hs in the same directory.
module Main where

import GHC
import GHC.Paths ( libdir )
import DynFlags
import Unsafe.Coerce

main :: IO ()
main =
    defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
      result <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "Plugin.hs" Nothing
        setTargets [target]
        r <- load LoadAllTargets
        case r of
          Failed    -> error "Compilation failed"
          Succeeded -> do
            setContext [IIModule (mkModuleName "Plugin")]
            result <- compileExpr ("Plugin.getInt")
            let result' = unsafeCoerce result :: Int
            return result'
      print result

和插件:

-- Plugin.hs
module Plugin where

getInt :: Int
getInt = 33

8470
2018-05-29 05:55


起源



答案:


问题是你正在使用 IIModule。这表示您希望将模块及其中的所有内容(包括未导出的内容)放入上下文中。它与...基本相同 :load 在GHCi中带星号。正如您所注意到的,这仅适用于解释代码,因为它让您“查看”模块。

但这不是你需要的。你想要的是像你使用的那样加载它 :module 或者 import 声明,适用于已编译的模块。为此,你使用 IIDecl 这需要你可以进行的进口申报 simpleImportDecl

setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")]

14
2018-05-29 06:15