2016-12-10 8 views
2

と言って、データベースに接続してクエリを実行したいとします。私は古い接続を再利用し、古い接続が壊れたときに再接続すると、データベースへの新しい接続を毎回持っていたくない、この場合のモナドの使い方は?

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と思います。

答えて

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 
関連する問題