2013-05-29 5 views
11

GHC API를 사용하여 Haskell 모듈을 동적으로 컴파일하고로드하려고합니다. API가 한 버전에서 다른 버전으로 상당히 변동한다는 것을 이해합니다. 따라서 GHC 7.6. *에 대해 구체적으로 말하고 있습니다.동적으로 컴파일 된 하스켈 모듈로드 - 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 

그리고 플러그인 : 당신이 IIModule을 사용하고 있는지

-- Plugin.hs 
module Plugin where 

getInt :: Int 
getInt = 33 

답변

14

문제입니다. 이는 수출되지 않은 물건을 포함하여 모듈과 그 안에 들어있는 모든 것을 컨텍스트에 가져 오기를 원한다는 것을 나타냅니다. GHCi에 별표가있는 :load과 본질적으로 같습니다. 그리고 당신이 알아 차렸 듯이 이것은 해석 된 코드에서만 작동합니다. 왜냐하면 모듈에서 "내부를 들여다 보자".

하지만 여기서 필요한 것은 아닙니다. 컴파일 된 모듈과 함께 작동하는 :module 또는 import 선언을 사용하는 것처럼로드하는 것이 좋습니다. 이를 위해 IIDecl을 사용합니다.이 선언은 simpleImportDecl으로 만들 수 있습니다.

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