我不明白yesod中的这种家庭用品是做什么用的
我浏览了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 在这些类中使用类型族有什么好处?
I went through yesod book and the source and learned pretty much how everything works. But before I write my own stuff, there is one thing in the scaffolded site that I just don't understand.
So I scaffold a site "copywww" and in the file CopyWWWState.hs there is the code:
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
]
The lines that I don't understand are the ones:
type AuthId CopyWWWState = UserId
type YesodDB CopyWWWState = SqlPersist
When I remove them, I get errors obviously, but I'm not sure why they are required in the first place. When I search the source for "UserId" or "SqlPersist" I come up with nothing that seems promising. What exactly does this code need to be there for? What benefit does yesod get from using type families in these classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
脚手架中发生的很多事情可能不会立即显而易见。在配置/模型中,有一个持久实体定义如下:
这将创建一个 User 类型,它是 PersistEntity 的一个实例,以及一个 UserId 类型,其用途如下:
脚手架放入的原因:
只是用户是逻辑参考点。现在,在您的代码中,每当您调用
requireAuth
时,您都会得到类似Handler User
的内容,并且requireAuthId
将为您提供一个Handler UserId
相当于处理程序(关键用户)
。您可以随意将它们更改为您想要的任何内容,但您必须更改 YesodAuth 类型类实例中的一些其他函数。希望这有帮助。耶索德摇滚。需要一两周的时间才能感受到它是如何粘在一起的,但当你这样做时,效果是非常强大的。
There's quite a bit going on in the scaffold that might not be immediately obvious. In the config/model, there is a persistent entity defined something like:
This will create a type User which is an instance of PersistEntity and a type UserId which is used as such:
The reason that the scaffold puts in:
is just that user is a logical reference point. Now, in your code, anytime you call
requireAuth
you'll get something likeHandler User
andrequireAuthId
will give you aHandler UserId
which is equivalent toHandler (Key User)
. You're free to change these to anything you'd like, but you'll have to change some of the other functions in the YesodAuth typeclass instance.Hope this helps. Yesod rocks. takes a week or two to get the feel of how it sticks together but when you do things like this are quite powerful.
类型族类似于功能依赖。它们都提供了一种通过多个参数抽象类型类的方法,同时让类型检查器满意。本地类型仅意味着您有一个由实例绑定的额外参数。这意味着,实例可以自行决定在该位置使用哪种类型。实例还可以使用更通用的类型而不是特定的类型来为用户提供选择。就您而言,您可能依赖这样一个事实:您的数据库类型
YesodDB
实际上是一个 SQL 数据库 (SqlPersist
)。因此需要此信息来满足类型检查器的要求。Type families are similar to functional dependecies. They both provide a way to abstract a typeclass over more than one parameter while keeping the typechecker happy. The local
type
just means, that you have an extra parameter that is bound by the instance. This means, that the instance can decide by itself which type to use at that place. An instance may also use a more general type instead of a specific to give the user the choice. In your case, you possibly rely on the fact, that ypur database typeYesodDB
is in fact a SQL database (SqlPersist
). So this information is needed to satisfy the typechecker.