2013-05-29 11 views
11

GHC APIを使用してHaskellモジュールを動的にコンパイルしてロードしようとしています。私は、APIがあるバージョンから別のバージョンにかなり変動していることを理解していますので、具体的にGHC 7.6についてお話しています*。動的にコンパイルされたHaskellモジュールをロードする - GHC 7.6

MacOSとLinuxで同じコードを実行しようとしました。どちらの場合も、Pluginモジュールは正常にコンパイルされますが、ロード時に次のエラーが発生します。thisの問題は、モジュールがホストプログラムの同じ実行でコンパイルされた場合にのみロードされます。

-- 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 

答えて

14

問題は、あなたがIIModuleを使用していることです。これは、エクスポートされていないものを含め、モジュールとその中のすべてをコンテキストに持ち込むことを示します。これは、GHCiにアスタリスクが付いた:loadと本質的に同じです。そしてあなたが気づいたように、これはインタプリタコードでのみ動作します。なぜなら、モジュールを「見て」みましょう。

しかし、ここで必要なのはそうではありません。コンパイルされたモジュールで動作する:moduleまたはimport宣言を使用した場合と同じように、ロードします。そのためにはIIDeclを使用します。この宣言はsimpleImportDeclで作成できます。

setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")] 
関連する問題