这个YesodAuth实例怎么了? [英] What's wrong with this YesodAuth instance?

查看:71
本文介绍了这个YesodAuth实例怎么了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚从当前的yesod支架迁移到最新的yesod-1.6.0yesod-auth-1.6.2.

I've just migrated from current yesod scaffold to latest yesod-1.6.0, yesod-auth-1.6.2.

instance YesodAuth App where
    type AuthId App = UserId

    -- ....

    authenticate creds = runDB $ do
        x <- getBy $ UniqueUser $ credsIdent creds
        case x of
            Just (Entity uid _) -> return $ Authenticated uid
            Nothing -> return $ UserError InvalidUsernamePass

在迁移之前,此代码运行良好.但是在发生以下错误之后.

Before migration this code worked well. But after the following error occurs.

.../src/Foundation.hs:212:26: error:
    • Could not deduce: m ~ HandlerFor site8
      from the context: (MonadHandler m, HandlerSite m ~ App)
        bound by the type signature for:
                   authenticate :: forall (m :: * -> *).
                                   (MonadHandler m, HandlerSite m ~ App) =>
                                   Creds App -> m (AuthenticationResult App)
        at src/Foundation.hs:212:5-16
      ‘m’ is a rigid type variable bound by
        the type signature for:
          authenticate :: forall (m :: * -> *).
                          (MonadHandler m, HandlerSite m ~ App) =>
                          Creds App -> m (AuthenticationResult App)
        at src/Foundation.hs:212:5-16
      Expected type: m (AuthenticationResult App)
        Actual type: HandlerFor site8 (AuthenticationResult App)
    • In the expression:
        runDB
          $ do x <- getBy $ UniqueUser $ credsIdent creds
               case x of
                 Just (Entity uid _) -> return $ Authenticated uid
                 Nothing -> return $ UserError InvalidUsernamePass
      In an equation for ‘authenticate’:
          authenticate creds
            = runDB
                $ do x <- getBy $ UniqueUser $ credsIdent creds
                     case x of
                       Just (Entity uid _) -> return $ Authenticated uid
                       Nothing -> return $ UserError InvalidUsernamePass
      In the instance declaration for ‘YesodAuth App’
    • Relevant bindings include
        authenticate :: Creds App -> m (AuthenticationResult App)
          (bound at src/Foundation.hs:212:5)
    |
212 |     authenticate creds = runDB $ do
    |                          ^^^^^^^^^^...

我不知道为什么它不能通过类型检查. runDB在与yesod-auth无关的地方效果很好.

I don't know why it can't pass type check. runDB works well in places not related to yesod-auth.

编辑:我提取了似乎相关的代码.

I extracted codes that seems relevant.

class (MonadResource m, MonadLogger m) => MonadHandler m where
    type HandlerSite m
    type SubHandlerSite m
    liftHandler :: HandlerFor (HandlerSite m) a -> m a
    liftSubHandler :: SubHandlerFor (SubHandlerSite m) (HandlerSite m) a -> m a

instance MonadHandler (HandlerFor site) where
    type HandlerSite (HandlerFor site) = site
    type SubHandlerSite (HandlerFor site) = site
    liftHandler = id
    {-# INLINE liftHandler #-}
    liftSubHandler (SubHandlerFor f) = HandlerFor f
    {-# INLINE liftSubHandler #-}

newtype HandlerFor site a = HandlerFor
    { unHandlerFor :: HandlerData site site -> IO a
    }
    deriving Functor

instance MonadHandler (HandlerFor site) where
    type HandlerSite (HandlerFor site) = site
    type SubHandlerSite (HandlerFor site) = site
    liftHandler = id
    {-# INLINE liftHandler #-}
    liftSubHandler (SubHandlerFor f) = HandlerFor f
    {-# INLINE liftSubHandler #-}

使用上面的定义,我想知道以下代码无法通过类型检查的原因.

With above definitions, I wonder the reason that the following cannot pass type check.

problem :: (MonadHandler m, HandlerSite m ~ App) => m ()
problem = (undefined :: HandlerFor App ())

    • Could not deduce: m ~ HandlerFor App
      from the context: (MonadHandler m, HandlerSite m ~ App)
        bound by the type signature for:
                   problem :: forall (m :: * -> *).
                          (MonadHandler m, HandlerSite m ~ App) =>
                          m ()
        at /intero/intero1940cny-TEMP.hs:210:1-52
      ‘m’ is a rigid type variable bound by
        the type signature for:
          problem :: forall (m :: * -> *).
                 (MonadHandler m, HandlerSite m ~ App) =>
                 m ()
        at /intero/intero1940cny-TEMP.hs:210:1-52
      Expected type: m ()
        Actual type: HandlerFor App ()
    • In the expression: (undefined :: HandlerFor App ())
      In an equation for ‘problem’: problem = (undefined :: HandlerFor App ())
    • Relevant bindings include
        problem :: m ()
          (bound at /intero/intero1940cny-TEMP.hs:211:1)

推荐答案

在每个runDB之前放置liftHandler ..

这篇关于这个YesodAuth实例怎么了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆