Cra*_*nes 7 compiler-construction api haskell dynamic-compilation ghc
我一直在尝试使用GHC API进行一些基本的动态代码编译,遵循此处的教程.
这段代码:
import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce
main :: IO ()
main =
defaultErrorHandler defaultDynFlags $ 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 [] [m]
value <- compileExpr ("Test.print")
do let value' = (unsafeCoerce value) :: String -> IO ()
return value'
func "Hello"
return ()
Run Code Online (Sandbox Code Playgroud)
应从另一个名为Test.hs的文件中获取print函数,加载它并运行其print函数.
我使用以下命令使用ghc版本7.4.1编译代码:
ghc -package ghc --make Api.hs
Run Code Online (Sandbox Code Playgroud)
但是收到以下错误:
Api.hs:8:25:
Couldn't match expected type `Severity' with actual type `Settings'
Expected type: LogAction
Actual type: Settings -> DynFlags
In the first argument of `defaultErrorHandler', namely
`defaultDynFlags'
In the expression: defaultErrorHandler defaultDynFlags
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我已经检查了GHC API文档但是我对这种事情的理解还不够深入.
该教程已过时.在ghc-7.0.*和之前,类型defaultErorHandler是
defaultErrorHandler :: (ExceptionMonad m, MonadIO m) => DynFlags -> m a -> m a
Run Code Online (Sandbox Code Playgroud)
而且defaultDynFlags只是一个价值.
截至ghc-7.2.*,类型defaultErrorHandler为
defaultErrorHandler :: (ExceptionMonad m, MonadIO m) => LogAction -> m a -> m a
Run Code Online (Sandbox Code Playgroud)
defaultDynFlags 是一个功能
defaultDynFlags :: Settings -> DynFlags
Run Code Online (Sandbox Code Playgroud)
并且LogAction是同义词
type LogAction = Severity -> SrcSpan -> PprStyle -> Message -> IO ()
Run Code Online (Sandbox Code Playgroud)
在7.6,它已经改变了,我们现在有了
defaultErrorHandler :: (ExceptionMonad m, MonadIO m) => FatalMessager -> FlushOut -> m a -> m a
Run Code Online (Sandbox Code Playgroud)
同
type FatalMessager = String -> IO ()
Run Code Online (Sandbox Code Playgroud)
并FlushOut成为一个newtype包装IO ().
我不太熟悉GHC Api(对我而言是一个过快的目标),所以我不确定工作代码应该是什么样子,但对于7.2和7.4系列,第一个参数defaultErrorHandler应该是defaultLogAction.
另外的类型setContext发生了变化,我不知道如果我有什么你想要做什么,但它编译(7.4.2,但你还需要ghc-paths包除了ghc对GHC.Paths模块) -我还没有尝试然而,跑吧.
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 ()
return value'
func "Hello"
return ()
Run Code Online (Sandbox Code Playgroud)