2016-12-10 4 views
2

Sagen wir, ich möchte eine Verbindung zu einer Datenbank herstellen und eine Abfrage durchführen. Ich entscheide, Monade zu verwenden, wie dies zu implementieren:Wie benutzt man Monad in diesem Fall?

queryDatabase :: IO String 
... 

doSomeQuery :: IO() 
doSomeQuery = do 
    conn <- connectToDatabase 
    result <- queryDatabase conn 
    return() 

doQueryForever :: IO() 
doQueryForever = forever doSomeQuery 

Aber ich will nicht, eine neue Verbindung zur Datenbank jedes Mal, ich mag die alte Verbindung wieder zu verwenden und wieder, wenn die alte Verbindung unterbrochen. So, Redesign ich mein Programm wie folgt aus:

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 

Die Frage ist: Wie kann ich die neue Verbindung machen nur durch Querydatabase Funktion geschaffen werden? Wenn forever Funktion erneut ausgeführt wird, denke ich, dass conn es die alte Verbindung verwendet.

Antwort

2

doQueryForever sollte eine Verbindung als Argument nehmen. Wenn eine Abfrage fehlschlägt, rufen Sie sie rekursiv mit einer neuen Verbindung auf. Wenn eine Abfrage erfolgreich ist, rufen Sie sie rekursiv mit der bestehenden Verbindung auf. Der erste Anruf muss natürlich auch die erste Verbindung herstellen.

handleResult result = ... 
runQueries = connectToDatabase >>= doQueryForever 

doQueryForever conn = do 
    result <- queryDatabase conn 
    case result of 
     Left _ -> runQueries 
     Right s -> handleResult s >> doQueryForever conn 

runQueries 
Verwandte Themen