2016-12-10 3 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 
Смежные вопросы