GHC API要求在調用之前進行一些初始化。具體而言,parseStaticFlags
只能被調用一次。通過Haskell中的unsafePerformIO創建全局變量
我有多個函數可以調用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)
然而,我不記得它是如何完成的。此代碼位於包裝GhcMonad
的monad的runMonad
函數中。我很清楚,使用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)
啊,我應該使用'IORef'而不是'MVar'。 – vivian
不,MVar很好。事實上MVar更好,因爲即使在併發的情況下它也能工作。 – augustss
我使用'MVar'時,程序掛起。 – vivian