Haskell do notation vs (>>) operator, happstack routing with 'method'



我正在学习Haskell,我也在努力学习happstack服务器。

我遵循http://happstack.com/docs/crashcourse/index.html#matching-on-request-method-get-post-etc的指南,他们对'dir'和'method'函数的使用在我的情况下不起作用。

我正试图将路由部分拆分为辅助函数,因为我很难理解如何正确处理关于do块,单元('()')类型和单子的返回类型。

我的学习器项目的存储库还没有公开,所以我将把相关代码完整地粘贴在这里。

编辑:下面的代码使用制表符缩进

main :: IO ()
--main = simpleHTTP nullConf $ ok "Hello, Haskell!!!"
main = simpleHTTP nullConf $ msum
[
dir "signup" $ serveFile (asContentType "text/html") "static/index.html",
dir "static" $ serveDirectory DisableBrowsing [] "static",
dir "api" api
--do dir "account" $ ok $ toResponse "account page",
--do dir "welcome" $ ok $ toResponse "welcome page",
----dir "api" $ ok $ toResponse "api endpoint",
----do dir "api" $ dir "person" (do method PUT
----                ok $ toResponse "api/person"),
--(do dir "api" $ apiRouting),
--do dir "static" $ serveDirectory DisableBrowsing [] "static"
----seeOther "welcome" ""
]
--apiRouting :: (ToMessage a) => ServerPartT IO a
--apiRouting = do
--  dir "person" (do method PUT ok $ toResponse "api/person")
--personHandler :: ServerPartT IO String
--personHandler = return (method PUT (return ok $ toResponse "api/person"))
api :: ServerPartT IO Response
api = msum
[
dir "person" person
]
person :: ServerPartT IO Response
-- this works
-- person = ok $ toResponse "api/person"
--so does this
--person = msum
--  [
--      ok $ toResponse "api/person"
--  ]
person = msum
[
--so, method PUT does nothing besides control which code branch is ran, based on the request
--that is why the happstack tutorial was using do notation
--but for some reason, do notation did not work when I tried it
--if it was because of whitespace or indentation, that's just silly
--this is the same as the happstack guide, doesn't work because "Couldn't match type ‘()’ with ‘Response -> ServerPartT IO Response’"
(do method PUT
ok $ toResponse "api/person put")
--this works and I think this syntax is nicer, but why does the do block not work?
--the thing1 >> thing2 operator does thing1, ignores any return value it might have had, and then returns the result of thing2
--method PUT >> (ok $ toResponse "api/person put")
]

由于某种原因,do方法的PUT方式不起作用,但'>>'方式可以。

我担心do块没有返回我想要的结果,所以我尝试使用'return'语句,但是没有效果。

在Happstack指南中,它看起来像这样:

main :: IO ()
main = simpleHTTP nullConf $ msum
[ do dir "foo" $ do method GET
ok $ "You did a GET request on /foon"
, do method GET
ok $ "You did a GET request.n"
, do method POST
ok $ "You did a POST request.n"
]

我试过下面的方法,但是行不通。

person = msum
[
--so, method PUT does nothing besides control which code branch is ran, based on the request
--that is why the happstack tutorial was using do notation
--but for some reason, do notation did not work when I tried it
--if it was because of whitespace or indentation, that's just silly
--this is the same as the happstack guide, doesn't work because "Couldn't match type ‘()’ with ‘Response -> ServerPartT IO Response’"
do method PUT
(return (ok $ toResponse "api/person put"))
--this works and I think this syntax is nicer, but why does the do block not work?
--the thing1 >> thing2 operator does thing1, ignores any return value it might have had, and then returns the result of thing2
--method PUT >> (ok $ toResponse "api/person put")
]

我认为做块返回他们的最后一个语句的结果,但从错误消息看起来像'do方法PUT'部分只是返回'()',我理解为类似于其他语言中的void或单元类型。

我正在学习Haskell,但是当我尝试做一些像这样的实践学习时,我遇到了一堆陷阱。

编辑:整个编译错误

web/app/Main.hs:72:20: error:
• Couldn't match type ‘()’ with ‘ServerPartT IO Response’
Expected: m0 (m1 Response) -> ServerPartT IO Response
Actual: m0 (m1 Response) -> ()
• In the result of a function call
In a stmt of a 'do' block:
method PUT (return (ok $ toResponse "api/person put"))
In the expression:
do method PUT (return (ok $ toResponse "api/person put"))
|
72 |                 do method PUT
person = msum
[
do method PUT
(return (ok $ toResponse "api/person put"))
]

导致错误:

• Couldn't match type ‘()’ with ‘ServerPartT IO Response’
Expected: m0 (m1 Response) -> ServerPartT IO Response
Actual: m0 (m1 Response) -> ()

,因为do块中的缩进不正确。这里的"return"关键字也不正确。

'do'块的对齐规则是,'do'块之后的第一个单词的第一个字符成为do块的所有后续行必须对齐的列值。

因为'method'中的'm'没有与do块中的第二条语句对齐,所以do块实际上只包含do method PUT内容。编辑:太缩进的行实际上被解释为method PUT表达式的延续,成为do method PUT (return (ok $ toResponse "api/person put"))谢谢,本!

Happstack 'method'函数的返回类型为

ghci> :t method
method
:: (Happstack.Server.Internal.Monads.ServerMonad m, MonadPlus m,
Happstack.Server.Routing.MatchMethod method) =>
method -> m ()

,所以do块` `返回的值` `;结果只是m(),导致错误。

如果您使用制表符而不是空格,则必须将第一个关键字放在创建块的语句后面,如'do',放在新行上。

person :: ServerPartT IO Response
person = msum
[
do
method PUT
ok $ toResponse "api/person put",
do
method GET
ok $ toResponse "api/person get",
do
method DELETE
ok $ toResponse "api/person delete"
]

编辑:读这个

维基手册中的示例如下,解决这些空白相关问题的另一种方法是使用花括号和分号语法:

do { putStr "Hello"
; putStr " "
; putStr "world!"
; putStr "n" }

相关内容

  • 没有找到相关文章

最新更新