2013-05-29 29 views
11

Tôi đang cố gắng biên dịch động và tải mô-đun Haskell bằng API GHC. Tôi hiểu rằng API biến động khá nhiều từ phiên bản này sang phiên bản khác nên tôi đang nói cụ thể về GHC 7.6. *.Tự động tải mô-đun Haskell đã biên dịch - GHC 7.6

Tôi đã thử chạy cùng một mã trên MacOS và Linux. Trong cả hai trường hợp, mô đun Plugin biên dịch tốt nhưng cho lỗi sau khi tải: Cannot add module Plugin to context: not interpreted

Vấn đề tương tự như ở mô-đun this nơi mô-đun sẽ chỉ tải nếu nó được biên dịch trong cùng một chương trình máy chủ.

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

Và plugin:

-- Plugin.hs 
module Plugin where 

getInt :: Int 
getInt = 33 

Trả lời

14

Vấn đề là bạn đang sử dụng IIModule. Điều này cho thấy rằng bạn muốn mang theo mô-đun và mọi thứ trong đó, bao gồm các nội dung không được xuất vào ngữ cảnh. Về cơ bản, nó giống như :load có dấu hoa thị trong GHCi. Và như bạn đã nhận thấy, điều này chỉ làm việc với mã giải thích vì nó cho phép bạn "nhìn vào bên trong" mô-đun.

Nhưng đó không phải là những gì bạn cần ở đây. Những gì bạn muốn là tải nó như thể bạn đã sử dụng :module hoặc khai báo import, hoạt động với các mô-đun được biên dịch. Để làm điều đó, bạn sử dụng số IIDecl để khai báo nhập khẩu mà bạn có thể thực hiện với simpleImportDecl:

setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")] 
Các vấn đề liên quan