I have been trying to get some basic dynamic code compilation working using the GHC API by following a tutorial found here.
This code:
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 ()
Should get the print function from another file called Test.hs, load it and run its print function.
I compile the code with ghc version 7.4.1 using the command:
ghc -package ghc --make Api.hs
But receive the following error:
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
What am I doing wrong? I have checked the GHC API docs but am not well versed enough in this kind of thing to understand most of it.
The tutorial is out of date. In ghc-7.0.* and previous, the type of
defaultErorHandler
wasand
defaultDynFlags
was just a value.As of ghc-7.2.*, the type of
defaultErrorHandler
isdefaultDynFlags
is a functionand
LogAction
is a synonymIn 7.6, it has changed again, we now have
with
and
FlushOut
being anewtype
wrapper aroundIO ()
.I'm not very familiar with the GHC Api (a too fast-moving target for me), so I'm not sure how the working code should look like, but for the 7.2 and 7.4 series, the first argument to
defaultErrorHandler
should probably bedefaultLogAction
.Also the type of
setContext
has changed, I don't know if what I have does what you want, but it compiles (with 7.4.2; but you also need theghc-paths
package in addition toghc
for theGHC.Paths
module) - I haven't tried to run it, though.Here is a complete example for dynamic loading, also hosted here:
DynLoad.hs
And here is an example file to load:
DynTest.hs