我正在学习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" }