Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The answer to this question has been given to me elsewhere. The GHC API is capable of doing this. Here are two functions, one of which compiles <code>Target.hs</code>, while the other accesses <code>Target.accessMe</code> (and doesn't require the source code of the <code>Target</code> module to be there anymore).</p> <pre><code>import GHC import DynFlags compile :: String -&gt; IO SuccessFlag compile name = defaultRunGhc $ do dynflags &lt;- getSessionDynFlags let dynflags' = dynflags -- You can change various options here. setSessionDynFlags dynflags' -- (name) can be "Target.hs", "Target", etc. target &lt;- guessTarget name Nothing addTarget target load LoadAllTargets -- Runs something like "ghc --make". </code></pre> <p>That's a function that compiles a given module and returns whether compilation succeeded or not. It uses a <code>defaultRunGhc</code> helper function that is defined as:</p> <pre><code>import GHC.Paths (libdir) defaultRunGhc :: Ghc a -&gt; IO a defaultRunGhc = defaultErrorHandler defaultDynFlags . runGhc (Just libdir) </code></pre> <p>And now a function for fetching a value from the compiled module. The module's source code need not be present at this point.</p> <pre><code>import Unsafe.Coerce (unsafeCoerce) fetch :: String -&gt; String -&gt; IO Int -- Assumes we are fetching an Int value. fetch name value = defaultRunGhc $ do -- Again, you can change various options in dynflags here, as above. dynflags &lt;- getSessionDynFlags let m = mkModule (thisPackage dynflags) (mkModuleName name) setContext [] [(m, Nothing)] -- Use setContext [] [m] for GHC&lt;7. fetched &lt;- compileExpr (name ++ "." ++ value) -- Fetching "Target.accessMe". return (unsafeCoerce fetched :: Int) </code></pre> <p>And that's it!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload