我不明白yesod中的这种家庭用品是做什么用的

发布于 2024-11-14 11:07:12 字数 1132 浏览 5 评论 0原文

我浏览了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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

摘星┃星的人 2024-11-21 11:07:12

脚手架中发生的很多事情可能不会立即显而易见。在配置/模型中,有一个持久实体定义如下:

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 相当于处理程序(关键用户)。您可以随意将它们更改为您想要的任何内容,但您必须更改 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:

User
  name String
  foo String

This will create a type User which is an instance of PersistEntity and a type UserId which is used as such:

instance PersistEntity User where
  ...
  Key User = UserId

The reason that the scaffold puts in:

type AuthId CopyWWWState = UserId

is just that user is a logical reference point. Now, in your code, anytime you call requireAuth you'll get something like Handler User and requireAuthId will give you a Handler UserId which is equivalent to Handler (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.

最丧也最甜 2024-11-21 11:07:12

类型族类似于功能依赖。它们都提供了一种通过多个参数抽象类型类的方法,同时让类型检查器满意。本地类型仅意味着您有一个由实例绑定的额外参数。这意味着,实例可以自行决定在该位置使用哪种类型。实例还可以使用更通用的类型而不是特定的类型来为用户提供选择。就您而言,您可能依赖这样一个事实:您的数据库类型 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 type YesodDB is in fact a SQL database (SqlPersist). So this information is needed to satisfy the typechecker.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文