通过Haskell中的unsafePerformIO实现全局变量
GHC API要求在调用之前进行一些初始化。具体来说,通过Haskell中的unsafePerformIO实现全局变量,haskell,ghc,ghc-api,Haskell,Ghc,Ghc Api,GHC API要求在调用之前进行一些初始化。具体来说,parseStaticFlags只能调用一次 我有一些函数可以多次调用runGhc::MaybeFilePath::Ghc a->IO a来运行一些Ghc-API方法。但是,有些初始化应该只在第一次调用该函数时发生 我似乎记得从Yisource可以创建一个全局变量,比如 ghcInitialised :: MVar (Bool,[String]) ghcInitialised = unsafePerformIO $ newMVar (Fals
parseStaticFlags
只能调用一次
我有一些函数可以多次调用runGhc::MaybeFilePath::Ghc a->IO a
来运行一些Ghc-API方法。但是,有些初始化应该只在第一次调用该函数时发生
我似乎记得从Yi
source可以创建一个全局变量,比如
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])
因此,在调用runGhc
的一元操作中,我们可以
(init,flags) <- readMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
(init,flags) <- takeMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
因此,在调用runGhc
的一元操作中,我们可以
(init,flags) <- readMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
(init,flags) <- takeMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
(初始化,标志)请参阅。它展示了如何使用一个全局计数器,每次你看到它时它都会“滴答”一声。您不需要计数器,但只需将True
放入计数器,而不是+1
或者,更好的是,您将初始化代码放入unsafePerformIO
,(当然由if
保护)。您需要关闭内联。
另一件重要的事情:类型必须是monomorph(=没有类型变量),否则您可能会为每个实际类型计算unsafePerformIO
{-# NOINLINE ghcInitialised #-}
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])
啊,我应该使用IORef
而不是MVar
。不,MVar很好。MVar实际上更好,因为它甚至可以与并发一起工作。当我使用MVar
s时,我的程序挂起了。你的readMVar
应该是takeMVar
,否则putMVar
会被阻塞。但是要小心,如果您切换到takeMVar
,您将需要putMVar
来匹配它,即使它已经初始化。