2011-05-24 71 views
1

哈斯克爾單子MSUM在HappStack

http://happstack.com/docs/crashcourse/HappstackState.html

當我運行的服務器,通過

  • 1偷看計數器增加時,我偷看
  • 2時,我不偷看

有問題的代碼是:

handlers :: ServerPart Response 
handlers = 
    msum [ dir "peek" $ do c <- query PeekCounter 
         ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c) 
     , do c <- update (AddCounter 1) 
      ok $ toResponse $ "New count is: " ++ show (unCounter c) 
     ] 

然而,當我通過

  • 0它修改爲

    handlers :: ServerPart Response 
    handlers = 
        msum [ dir "peek" $ do c <- query PeekCounter 
              ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c) 
         , do ok $ toResponse $ "Stop here." 
         , do c <- update (AddCounter 1) 
           ok $ toResponse $ "New count is: " ++ show (unCounter c) 
         ] 
    

    的計數器增加,當我偷看

  • 1時,我不偷看

是那預期的行爲?感覺好像msum中的第二個monad即使在我偷看時也是「漏」了出來。

回答

5

計數正在增加額外的時間,因爲瀏覽器在每次加載頁面時都會請求/favicon.ico。由於最後一條路線是全面的,對/favicon.ico的請求會導致增量。

最簡單的解決方法是添加nullDir,這樣它只做了/一個增量,

handlers :: ServerPart Response 
handlers = 
msum [ dir "peek" $ do c <- query PeekCounter 
        ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c) 
    , do nullDir 
      c <- update (AddCounter 1) 
      ok $ toResponse $ "New count is: " ++ show (unCounter c) 
    ] 

我已經更新與變革的教程,以避免進一步的混亂。爲了證實它確實是事情搞亂了/favicon.ico要求,我們可以明確地處理一個圖標的要求:

handlers :: ServerPart Response 
handlers = 
    msum [ dir "peek" $ do c <- query PeekCounter 
          ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c) 
     , dir "favicon.ico" $ notFound (toResponse "sorry, no favicon.ico") 
     , do c <- update (AddCounter 1) 
       ok $ toResponse $ "New count is: " ++ show (unCounter c) 
     ] 

現在我們看到預期的行爲。

總之,Happstack沒有任何問題。瀏覽器向不是/偷看的網址發出1或2個請求,因此計數增加了一次或兩次。這是應用程序的預期行爲。但是,由於人們不期待/favicon.ico請求,它也會導致令人驚訝的行爲。所以現在應用程序已經改變,只有兩個有效的網址,/ peek和/。任何其他結果在404.

感謝您的報告!