1

有人可以解释默认快照项目模板中发生了什么吗?

--------------------------------------------------------------------------
-- | Handle login submit
handleLoginSubmit :: Handler App (AuthManager App) ()
handleLoginSubmit =
    loginUser "login" "password" Nothing
              (\_ -> handleLogin err) (redirect "/")
  where
    err = Just "Unknown user or password"

-- | Render login form
handleLogin :: Maybe T.Text -> Handler App (AuthManager App) ()
handleLogin authError = heistLocal (bindSplices errs) $ render "login"
  where
    errs = [("loginError", textSplice c) | c <- maybeToList authError]

 | The application's routes.
routes :: [(ByteString, Handler App App ())]
routes = [ ("/login",    with auth handleLoginSubmit)
         , ("/logout",   with auth handleLogout)
         , ("/new_user", with auth handleNewUser)
         , ("",          serveDirectory "static")
         ]
  1. 为什么返回()?
  2. “控制器”(正如您在 MVC 中所说的那样)功能的标准签名是什么?
  3. 它如何知道index.tpl用作/路线的模板?
  4. 我如何摆脱身份验证层,比如我只想制作一个简单的个人网络应用程序?

文档和教程主要涵盖了 snapplet(或模板),但没有涵盖任何 Haskell。很高兴看到一个如何编写书店之类的应用程序或博客的示例(官方 snap 网站将他们的博客条目存储在 markdown 中 - 所以我不确定那里发生了什么)。

4

1 回答 1

5

我自己正在学习Haskell,对Snap一无所知,但我可以尽力回答我能看到的:

1)

Snap.Snaplet模块定义了一个类型:Handler b v a.
因此,anyHandler具有三个类型参数:bva
此外,(Handler b v)在同一模块中声明为Monad. 这可能会告诉你最后一个a参数的用途。

IO是另一个例子Monad
IO ()做与 IO 有关的“某事”,然后返回()一个空值。
IO a做与 IO 有关的“某事”,然后返回其他类型的东西a

例如,x <- putStrLn "text"因为 putStrLn 有返回类型,所以这样做并没有什么意义IO ()。从技术上讲,你可以,但它通常没用。putStrLn做 IO,仅此而已,拒绝将任何东西传递给未来的功能。具体来说,它会在控制台上打印一些东西,但它不会告诉程序的其余部分它这样做了。

str <- getLine有道理,因为getLine有 type IO String。它执行 IO,然后讲述str一个String. 它产生一个函数的其余部分可以直接使用的结果。

对于Handler,您可能会忘记处理程序的作用并像这样查看它:

let M = Handler b v
M被宣布为单子。
所以,M a做“某事”,然后返回一个a.
M ()做“某事”并且不返回任何东西。

从中您可能可以了解一些有关handleLogin正在执行的功能的信息。Handler它接受它的论点,并且可能基于这些论点/对这些论点做一些事情。之后,假设没有错误,程序移动到下一行,而不告诉下一行的函数发生了什么。

Snap 中有一些函数会返回 a Handler,而不是()最后一个参数。如果你看到这样的函数,这意味着它带有一个有意义的返回值。

4)

我怀疑这些模板更多的是示例而不是您打算从中构建的东西,但它们都是手动编写的,所以我认为您可以根据需要删除身份验证步骤。该类型App在“Application.hs”中定义,您可以在其中删除其auth参数。然后,您可以在项目的其余部分中删除对它的引用。

于 2012-06-26T09:19:55.727 回答