我浏览了yesod书和来源,并了解了一切如何运作。但在我写自己的东西之前,脚手架网站中有一件事我不明白。
所以我在一个网站“copywww”上加了一个网站,在文件CopyWWWState.hs中有代码:
instance YesodPersist CopyWWWState where
type YesodDB CopyWWWState = SqlPersist
runDB db = liftIOHandler
$ fmap connPool getYesod >>= Settings.runConnectionPool db
instance YesodAuth CopyWWWState where
type AuthId CopyWWWState = UserId
-- Where to send a user after successful login
loginDest _ = RootR
-- Where to send a user after logout
logoutDest _ = RootR
getAuthId creds = runDB $ do
x <- getBy $ UniqueUser $ credsIdent creds
case x of
Just (uid, _) -> return $ Just uid
Nothing -> do
fmap Just $ insert $ User (credsIdent creds) Nothing
authPlugins = [ authOpenId
, authEmail
]
我不理解的那些是:
type AuthId CopyWWWState = UserId
type YesodDB CopyWWWState = SqlPersist
当我删除它们时,显然会出现错误,但我不确定为什么它们首先是必需的。当我在源代码中搜索“UserId”或“SqlPersist”时,我想出了一些看起来很有希望的东西。这段代码究竟需要什么? yesod在这些类中使用类型系列有什么好处?
答案 0 :(得分:7)
脚手架中有很多可能不会立即出现的情况。在config / model中,有一个持久化实体定义如下:
User
name String
foo String
这将创建一个类型User,它是PersistEntity的一个实例,UserId类型是这样使用的:
instance PersistEntity User where
...
Key User = UserId
脚手架放入的原因:
type AuthId CopyWWWState = UserId
只是用户是一个逻辑参考点。现在,在您的代码中,只要您拨打requireAuth
,就会得到类似Handler User
和requireAuthId
的内容,会为您提供相当于Handler UserId
的{{1}}。您可以随意将这些更改为您想要的任何内容,但您必须更改YesodAuth类型类实例中的其他一些函数。
希望这会有所帮助。 Yesod岩石。花一两个星期的时间来感受它如何粘在一起,但是当你做这样的事情是相当强大的。
答案 1 :(得分:2)
类型系列与功能依赖类似。它们都提供了一种方法来在多个参数上抽象类型类,同时保持typechecker的快乐。本地type
只是意味着您有一个受实例约束的额外参数。这意味着,实例可以自己决定在该位置使用哪种类型。实例也可以使用更通用的类型而不是特定类型来为用户提供选择。在您的情况下,您可能依赖于这样的事实,即ypur数据库类型YesodDB
实际上是SQL数据库(SqlPersist
)。所以需要这些信息才能满足类型检测器的需要。