Haskell Monads msum в HappStack - PullRequest
1 голос
/ 24 мая 2011

С

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)
         ]

Однако, когда я изменяю его на

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)
         ]

Счетчик увеличивается на

  • 0, когда я смотрю
  • 1, когда я не смотрю

Это предполагаемое поведение?Такое ощущение, что вторая монада в msum «протекает», даже когда я делаю взгляд.

1 Ответ

6 голосов
/ 24 мая 2011

Счет увеличивается на дополнительное время, потому что браузер запрашивает /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 запроса к URL, которые не были / peek, и поэтому счетчик увеличивался один или два раза.Это было предполагаемое поведение приложения.Но, поскольку люди не ожидают запрос /favicon.ico, это также приводит к удивительному поведению.Так что теперь приложение было изменено, чтобы иметь только два действительных URL, / peek и /.Все остальное приводит к 404.

Спасибо за отчет!

...