HappStack 中的 Haskell Monads msum

发布于 2024-11-09 01:14:19 字数 1117 浏览 0 评论 0原文

来自

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

当我运行时服务器,

  • 时窥视2时,窥视计数器增加1
  • 当我不窥视

有问题的相关代码是:

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

1时,计数器增加

  • 窥视
  • 当我非窥视时

0是这样的预期的行为?即使我看了一下,感觉好像 msum 中的第二个 monad 正在“泄漏”。

From

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

When I run the server, the peek counter increases by

  • 1 when I peek
  • 2 when I do not peek

The relevant code in question is:

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

However, when I modify it to

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

The counter increases by

  • 0 when I peek
  • 1 when I non-peek

Is that the intended behaviour? It feels as if the second monad in msum is "leaking" even when I do a peek.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌伤ぢ 2024-11-16 01:14:19

由于浏览器每次加载页面时都会请求 /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 请求造成了混乱,我们可以显式处理对 favicon 的请求:

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没有任何问题。浏览器向非 /peek 的 URL 发出 1 或 2 个请求,因此计数增加了一两次。这是应用程序的预期行为。但是,由于人们没有预料到 /favicon.ico 请求,它也会导致令人惊讶的行为。所以现在应用程序已更改为只有两个有效的 url:/peek 和 /。其他任何情况都会导致 404。

感谢您的报告!

The count is being incremented an extra time because the browser requests /favicon.ico every time it loads the page. Since the last route is a catch-all, the request to /favicon.ico causes an increment.

The easiest fix is to add nullDir so that it only does an increment for /,

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

I have updated the tutorial with that change to avoid further confusion. To confirm that it really is the /favicon.ico request that is messing things up, we could explicitly handle the request for a favicon:

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

Now we see the expected behavior.

In summary, there is nothing wrong with Happstack. The browser was making 1 or 2 requests to urls that were not /peek, and so the count got incremented once or twice. That was the intended behavior of the application. But, since people aren't expecting the /favicon.ico request it also leads to surprising behavior. So now the app has been change to only have two valid urls, /peek and /. Anything else results in a 404.

Thanks for the report!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文