说,我想连接到数据库并进行一些查询。我决定使用monad这样实现:
queryDatabase :: IO String
...
doSomeQuery :: IO ()
doSomeQuery = do
conn <- connectToDatabase
result <- queryDatabase conn
return ()
doQueryForever :: IO ()
doQueryForever = forever doSomeQuery
但是,我不想每次都有一个新的数据库连接,我想重新使用旧连接并在旧连接断开时重新连接。所以,我重新设计了我的程序:
queryDatabase :: IO (Either Connection String)
-- when the connection is broken, return (Left oldConnection)
doSomeQuery :: IO ()
doSomeQuery = do
conn <- connectToDatabase
result <- queryDatabase conn
return ()
doQueryForever :: IO ()
doQueryForever = do
conn <- connectToDatabase -- Firstly, create a connection
forever $ do
result <- queryDatabase conn -- How can I update this conn when broken?
case result of
--
-- Here is the QUESTION.
-- If I create a New connection, it seems difficult for me to
-- make the new connection use by queryDatabase function.
--
Left oldConn -> createNewConnection
Right s -> putStrLn s
问题是:如何创建刚创建的新连接以供queryDatabase函数使用?当forever
函数再次运行时,我认为它使用的conn
是旧连接。
答案 0 :(得分:2)
doQueryForever
应该以连接为参数。查询失败时,使用新连接以递归方式调用它;当查询成功时,使用现有连接以递归方式调用它。当然,初始呼叫也需要进行第一次连接。
handleResult result = ...
runQueries = connectToDatabase >>= doQueryForever
doQueryForever conn = do
result <- queryDatabase conn
case result of
Left _ -> runQueries
Right s -> handleResult s >> doQueryForever conn
runQueries