Haskell Monads 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)
]
Тем не менее, когда я изменяю его
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 ответ
Счет увеличивается на дополнительное время, потому что браузер запрашивает /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.
Спасибо за отчет!