任务是创建动态链接库,它封装了数据库的艰苦工作。由于一些设计限制,我有一个定义的接口,它由许多功能组成。每个函数都接受一个参数并在数据库查询中使用它们。数据库连接应该在dll内部,应用程序不想打扰是否有任何连接。
初始化数据库连接然后将其提供给每个函数而不显式传递它的最佳方法是什么。
当然,我一般都喜欢使用State monad。但是dll并不是设计为有一个入口点。
答案 0 :(得分:2)
听起来您正在尝试创建可以从其他语言调用的DLL。如果是这样,那么你的所有功能都将存在于IO monad中。因此,您可以使用IORef来存储数据库连接对象。
更新(见下面的评论)
GHC与全局随机数生成器状态存在类似问题。以下是System.Random的相关源代码:
-- |Gets the global random number generator.
getStdGen :: IO StdGen
getStdGen = readIORef theStdGen
theStdGen :: IORef StdGen
theStdGen = unsafePerformIO $ do
rng <- mkStdRNG 0
newIORef rng
所以大概类似的东西对数据库连接起作用。是的,这是使用邪恶的unsafePerformIO,但有时你只是邪恶。
答案 1 :(得分:1)
您可以使用unsafePerformIO
“作弊”:
{-# NOINLINE globalVar #-}
globalVar :: MVar Integer
globalVar = unsafePerformIO (newMVar 17)
我对修复的API表示哀悼。