GHC API要求在调用之前进行一些初始化。具体来说,parseStaticFlags只能被调用一次。

我的函数可以多次调用runGhc :: MaybeFilePath :: Ghc a -> IO a来运行某些GHC API方法。但是,某些初始化仅应在第一次调用该函数时发生。

我似乎记得从Yi源代码中可以创建一个类似

ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])

这样在调用runGhc的单子动作中我们可以
(init,flags) <- readMVar ghcInitialised
when (not init) $ do
   ...
   (_,_,staticFlagWarnings) <- parseStaticFlags ...
   ...
   putMVar ghcInitialised (True,staticFlagWarnings)

但是,我不记得确切是怎么做的。此代码在包装runMonad的monad的GhcMonad函数中。我很清楚,使用unsafePerformIO并不是纯粹的或功能性的,但是(当时)这是获得实际结果的最佳方法。

[编辑:工作解决方案:
{-# NOINLINE ghcInitialised #-}
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])

这样在调用runGhc的单子动作中我们可以
(init,flags) <- takeMVar ghcInitialised
when (not init) $ do
   ...
   (_,_,staticFlagWarnings) <- parseStaticFlags ...
   ...
   putMVar ghcInitialised (True,staticFlagWarnings)

最佳答案

参见this answer。它显示了如何使用每次查看时都会“滴答”的全局计数器。您不需要计数器,但只需将+1放入其中,而不是True即可。

或者,甚至更好的是,将初始化代码放入unsafePerformIO中(当然由if保护)。

10-06 02:28