GHC API требует, чтобы некоторая инициализация произошла до вызова. В частности, parseStaticFlags
может быть вызван только один раз.
У меня есть функции, которые могут вызывать runGhc :: MaybeFilePath :: Ghc a -> IO a
несколько раз для запуска некоторых методов API GHC. Однако некоторая инициализация должна происходить только при первом вызове функции.
Кажется, я помню из 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
для монады, которая заключает в себе 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)